Track web-core frontend source
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 3m32s
41
web-core/.gitignore
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
coverage
|
||||||
|
output/
|
||||||
|
*.local
|
||||||
|
vite.config.js
|
||||||
|
vite.config.d.ts
|
||||||
|
src/assets/login/
|
||||||
|
|
||||||
|
/cypress/videos/
|
||||||
|
/cypress/screenshots/
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
src/types/auto-imports.d.ts
|
||||||
|
src/types/components.d.ts
|
||||||
|
src/views/scriptManage/components/ceshi.png
|
||||||
|
oss
|
||||||
|
|
||||||
|
backup
|
||||||
11
web-core/.prettierignore
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
build
|
||||||
|
.output
|
||||||
|
.nuxt
|
||||||
|
coverage
|
||||||
|
*.min.js
|
||||||
|
*.min.css
|
||||||
|
package-lock.json
|
||||||
|
pnpm-lock.yaml
|
||||||
|
yarn.lock
|
||||||
8
web-core/.prettierrc.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/prettierrc",
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": false,
|
||||||
|
"printWidth": 150,
|
||||||
|
"bracketSameLine": true,
|
||||||
|
"htmlWhitespaceSensitivity": "ignore"
|
||||||
|
}
|
||||||
259
web-core/LICENSE
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 补充协议 | Supplementary Agreement
|
||||||
|
|
||||||
|
> **补充协议 | Supplementary Agreement**
|
||||||
|
>
|
||||||
|
> 若您将本软件或其衍生版本以产品形式分发、销售或提供给**两个及以上独立的第三方主体**使用(无论采用买断、订阅、授权或任何其他商业模式),均须事先取得 HBAI-Ltd 的**书面商业授权**。
|
||||||
|
>
|
||||||
|
> If you distribute, sell, or provide this software (or any derivative) as a product to **two or more independent third parties** (regardless of business model: one-time purchase, subscription, licensing, etc.), you must obtain **written commercial authorization** from HBAI-Ltd prior to such use.
|
||||||
|
>
|
||||||
|
> **五个以内(含五个)**的法人主体作为联合运营方共同使用本软件,且不向联合体以外的第三方分发或提供服务的,视为**内部使用,无需商业授权**。
|
||||||
|
>
|
||||||
|
> **Five (5) or fewer** legal entities jointly operating and using this software internally, without distributing or providing services to parties outside the joint operation, are considered **internal use** and do not require commercial authorization.
|
||||||
|
>
|
||||||
|
> 在使用 Toonflow 的过程中,您不得删除或修改 Toonflow 控制台或应用程序中的标识或版权信息。
|
||||||
|
>
|
||||||
|
> You may not remove or modify any trademarks, logos, or copyright notices in the Toonflow console or application.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 永久免费场景 | Always Free — No Authorization Required
|
||||||
|
|
||||||
|
以下使用场景**永久免费**,无需任何授权:
|
||||||
|
|
||||||
|
The following uses are **always free** and require no authorization:
|
||||||
|
|
||||||
|
- ✅ 用 Toonflow 制作内容,在平台发布并获得分账 / Using Toonflow to produce content and earn platform revenue shares
|
||||||
|
- ✅ 二次开发,供自己团队内部使用 / Secondary development and modification for internal team use
|
||||||
|
- ✅ ≤ 5 个法人联合运营内部使用,不对外提供服务 / ≤5 legal entities operating jointly, internally only
|
||||||
|
- ✅ 个人学习、研究、非商业用途 / Personal learning, research, and non-commercial purposes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 授权定价 | Licensing Pricing
|
||||||
|
|
||||||
|
商业授权费用与被授权方业务规模挂钩:
|
||||||
|
|
||||||
|
Commercial licensing fees scale with the licensee's business scale:
|
||||||
|
|
||||||
|
| 阶段 | 年销售额 | 年费 |
|
||||||
|
|------|---------|------|
|
||||||
|
| 🌱 扶持期 / Nurture | < ¥10 万 / $10k | **免费 / Free** |
|
||||||
|
| 🚀 初创期 / Startup | ¥10–50 万 / $10k–$50k | ¥5,000 / 年 / year |
|
||||||
|
| 📈 成长期 / Growth | ¥50–150 万 / $50k–$150k | ¥20,000 / 年 / year |
|
||||||
|
| 🏢 规模期 / Scale | ¥150–500 万 / $150k–$500k | ¥80,000 / 年 / year |
|
||||||
|
| 🌐 企业级 / Enterprise | > ¥500 万 / $500k | 面议 / Negotiable |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AGPL 用户保护条款 | AGPL User Protection
|
||||||
|
|
||||||
|
> **不追溯条款 | Non-Retroactivity Clause**
|
||||||
|
>
|
||||||
|
> 本协议变更生效日期(v1.0.8 正式发布日)前,基于 AGPL-3.0 条款使用 Toonflow 的用户,其现有使用行为不受本协议变更的约束,继续按 AGPL-3.0 条款执行。
|
||||||
|
>
|
||||||
|
> Users who used Toonflow under AGPL-3.0 prior to the effective date of this change (v1.0.8 official release date) are not affected by this license change. Their existing usage continues under AGPL-3.0.
|
||||||
243
web-core/NOTICES.txt
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
Name: @eonova/v3-directives
|
||||||
|
License: MIT
|
||||||
|
Repository: N/A
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: @icon-park/vue-next
|
||||||
|
License: Apache-2.0
|
||||||
|
Repository: https://github.com/bytedance/IconPark
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: @tsconfig/node22
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/tsconfig/bases
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: @types/license-checker
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: @types/node
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: @types/uuid
|
||||||
|
License: MIT
|
||||||
|
Repository: N/A
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: @vitejs/plugin-vue
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/vitejs/vite-plugin-vue
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: @vue/eslint-config-prettier
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/vuejs/eslint-config-prettier
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: @vue/eslint-config-typescript
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/vuejs/eslint-config-typescript
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: @vue/tsconfig
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/vuejs/tsconfig
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: @vueuse/core
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/vueuse/vueuse
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: @vueuse/core
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/vueuse/vueuse
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: ant-design-vue
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/vueComponent/ant-design-vue
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: axios
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/axios/axios
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: class-variance-authority
|
||||||
|
License: Apache-2.0
|
||||||
|
Repository: https://github.com/joe-bell/cva
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: clsx
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/lukeed/clsx
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: dayjs
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/iamkun/dayjs
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: element-plus
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/element-plus/element-plus
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: eslint-plugin-oxlint
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/oxc-project/eslint-plugin-oxlint
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: eslint-plugin-vue
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/vuejs/eslint-plugin-vue
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: eslint
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/eslint/eslint
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: license-checker
|
||||||
|
License: BSD-3-Clause
|
||||||
|
Repository: https://github.com/davglass/license-checker
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: mammoth
|
||||||
|
License: BSD-2-Clause
|
||||||
|
Repository: https://github.com/mwilliamson/mammoth.js
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: npm-run-all2
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/bcomnes/npm-run-all2
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: oxlint
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/oxc-project/oxc
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: pinia-plugin-persistedstate
|
||||||
|
License: MIT
|
||||||
|
Repository: https://codeberg.org/praz/pinia-plugin-persistedstate
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: pinia
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/vuejs/pinia
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: prettier
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/prettier/prettier
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: sass
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/sass/dart-sass
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: typescript
|
||||||
|
License: Apache-2.0
|
||||||
|
Repository: https://github.com/microsoft/TypeScript
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: unplugin-auto-import
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/unplugin/unplugin-auto-import
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: unplugin-vue-components
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/unplugin/unplugin-vue-components
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: uuid
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/uuidjs/uuid
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: vite-plugin-lazy-import
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/x-extends/vite-plugin-lazy-import
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: vite-plugin-singlefile
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/richardtallent/vite-plugin-singlefile
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: vite
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/vitejs/vite
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: vue-router
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/vuejs/router
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: vue-tsc
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/vuejs/language-tools
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: vue
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/vuejs/core
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: vuedraggable
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/SortableJS/Vue.Draggable
|
||||||
|
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Name: vxe-table
|
||||||
|
License: MIT
|
||||||
|
Repository: https://github.com/x-extends/vxe-table
|
||||||
487
web-core/README.md
Normal file
@ -0,0 +1,487 @@
|
|||||||
|
<p align="center">
|
||||||
|
<strong>中文</strong> |
|
||||||
|
<a href="./docs/README.en.md">English</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
<img src="./docs/logo.png" alt="Toonflow Logo" height="120"/>
|
||||||
|
|
||||||
|
# Toonflow Web
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<b>
|
||||||
|
Toonflow 前端应用
|
||||||
|
<br />
|
||||||
|
基于 Vue 3 + TypeScript + Vite 构建的现代化 Web 界面
|
||||||
|
<br />
|
||||||
|
AI短剧工厂的用户操作端 🎨
|
||||||
|
</b>
|
||||||
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/HBAI-Ltd/Toonflow-web/stargazers">
|
||||||
|
<img src="https://img.shields.io/github/stars/HBAI-Ltd/Toonflow-web?style=for-the-badge&logo=github" alt="Stars Badge" />
|
||||||
|
</a>
|
||||||
|
<a href="https://www.gnu.org/licenses/agpl-3.0" target="_blank">
|
||||||
|
<img src="https://img.shields.io/badge/License-AGPL-blue.svg?style=for-the-badge" alt="AGPL License Badge" />
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/HBAI-Ltd/Toonflow-web/releases">
|
||||||
|
<img alt="release" src="https://img.shields.io/github/v/release/HBAI-Ltd/Toonflow-web?style=for-the-badge" />
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
> 🎯 **现代化前端架构**:采用 Vue 3 组合式 API、TypeScript 类型安全、Vite 极速构建,打造流畅的用户体验!
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# ⚠️ 重要提示
|
||||||
|
|
||||||
|
> **本仓库仅包含前端源代码,适用于开发者进行二次开发或定制。**
|
||||||
|
>
|
||||||
|
> 🎉 **如果您是普通用户,想要直接使用 Toonflow,请前往主仓库下载完整客户端:**
|
||||||
|
>
|
||||||
|
> | 平台 | 链接 |
|
||||||
|
> | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- |
|
||||||
|
> | <img src="https://img.shields.io/badge/GitHub-181717?style=flat&logo=github&logoColor=white" alt="GitHub" /> | 👉 [github.com/HBAI-Ltd/Toonflow-app](https://github.com/HBAI-Ltd/Toonflow-app) |
|
||||||
|
> | <img src="https://img.shields.io/badge/Gitee-C71D23?style=flat&logo=gitee&logoColor=white" alt="Gitee" /> | 👉 [gitee.com/HBAI-Ltd/Toonflow-app](https://gitee.com/HBAI-Ltd/Toonflow-app) |
|
||||||
|
>
|
||||||
|
> 主仓库包含:
|
||||||
|
>
|
||||||
|
> - ✅ 完整的桌面客户端
|
||||||
|
> - ✅ 后端服务
|
||||||
|
> - ✅ 开箱即用的安装包
|
||||||
|
> - ✅ 详细的使用教程
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🌟 技术栈
|
||||||
|
|
||||||
|
- **框架**:Vue 3.5+ (组合式 API)
|
||||||
|
- **构建工具**:Vite 5.4+
|
||||||
|
- **语言**:TypeScript 5.6+
|
||||||
|
- **状态管理**:Pinia 2.2+ (支持持久化)
|
||||||
|
- **路由**:Vue Router 4.4+
|
||||||
|
- **UI 组件库**:
|
||||||
|
- Ant Design Vue 4.2+
|
||||||
|
- Element Plus 2.13+
|
||||||
|
- VXE Table 4.17+
|
||||||
|
- **工具库**:
|
||||||
|
- Axios - HTTP 请求
|
||||||
|
- VueUse - Vue 组合式工具集
|
||||||
|
- Day.js - 日期处理
|
||||||
|
- Mammoth - Word 文档解析
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🎨 主要功能模块
|
||||||
|
|
||||||
|
Toonflow Web 提供了完整的短剧创作前端界面,包含以下核心模块:
|
||||||
|
|
||||||
|
- ✅ **项目管理**
|
||||||
|
创建、编辑和管理短剧项目,支持项目状态追踪和多项目并行开发。
|
||||||
|
|
||||||
|
- ✅ **原始文本编辑**
|
||||||
|
导入和编辑小说原文,支持 Word 文档解析,智能文本清洗和章节分割。
|
||||||
|
|
||||||
|
- ✅ **角色素材库**
|
||||||
|
管理角色设定、角色图片等素材,支持批量生成、手动上传和在线编辑。
|
||||||
|
|
||||||
|
- ✅ **大纲管理**
|
||||||
|
可视化编辑故事大纲和事件线,支持拖拽排序和智能生成。
|
||||||
|
|
||||||
|
- ✅ **剧本编辑器**
|
||||||
|
结构化剧本编辑界面,支持对话、场景、情绪等多维度标注。
|
||||||
|
|
||||||
|
- ✅ **分镜设计**
|
||||||
|
可视化分镜画布,支持拖拽布局、图像检测和 AI 对话式分镜生成。
|
||||||
|
|
||||||
|
- ✅ **视频配置**
|
||||||
|
配置视频生成参数,支持多家 AI 视频服务商切换和视频下载。
|
||||||
|
|
||||||
|
- ✅ **任务监控**
|
||||||
|
实时查看 AI 生成任务进度,支持任务队列管理和历史记录查询。
|
||||||
|
|
||||||
|
- ✅ **系统设置**
|
||||||
|
配置 AI 服务商、提示词模板、用户权限等系统级参数。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 📦 应用场景
|
||||||
|
|
||||||
|
- 短剧内容创作的前端操作界面
|
||||||
|
- AI 辅助编剧工具的可视化平台
|
||||||
|
- 分镜设计与视频生成的工作台
|
||||||
|
- 多人协作的剧本管理系统
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🚀 快速开始
|
||||||
|
|
||||||
|
## 💡 您是哪类用户?
|
||||||
|
|
||||||
|
| 用户类型 | 推荐方案 | GitHub | Gitee |
|
||||||
|
| ---------------------------------------------- | -------------- | -------------------------------------------------------- | ------------------------------------------------------- |
|
||||||
|
| 🎬 **普通用户** - 想直接使用 Toonflow 创作短剧 | 下载完整客户端 | [Toonflow-app](https://github.com/HBAI-Ltd/Toonflow-app) | [Toonflow-app](https://gitee.com/HBAI-Ltd/Toonflow-app) |
|
||||||
|
| 👨💻 **开发者** - 想修改前端代码或二次开发 | 继续阅读本文档 | 本仓库 | 本仓库 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 前置条件
|
||||||
|
|
||||||
|
在开发和运行本项目之前,请确保已安装:
|
||||||
|
|
||||||
|
- ✅ **Node.js**:23.11.1 或更高版本
|
||||||
|
- ✅ **Yarn**:1.22.0 或更高版本(推荐包管理器)
|
||||||
|
- ✅ **后端服务**:确保 Toonflow 后端服务已启动并可访问(可从 [GitHub](https://github.com/HBAI-Ltd/Toonflow-app) 或 [Gitee](https://gitee.com/HBAI-Ltd/Toonflow-app) 获取)
|
||||||
|
|
||||||
|
## 本地开发
|
||||||
|
|
||||||
|
### 1. 克隆项目
|
||||||
|
|
||||||
|
**GitHub:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/HBAI-Ltd/Toonflow-web.git
|
||||||
|
cd Toonflow-web
|
||||||
|
```
|
||||||
|
|
||||||
|
**Gitee(国内推荐):**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://gitee.com/HBAI-Ltd/Toonflow-web.git
|
||||||
|
cd Toonflow-web
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 安装依赖
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn install
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 启动开发服务器
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn dev
|
||||||
|
```
|
||||||
|
|
||||||
|
开发服务器默认运行在 `http://localhost:5173`,支持热模块替换(HMR)。
|
||||||
|
|
||||||
|
### 4. 构建生产版本
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 开发环境构建
|
||||||
|
yarn build:dev
|
||||||
|
|
||||||
|
# 生产环境构建
|
||||||
|
yarn build:prod
|
||||||
|
```
|
||||||
|
|
||||||
|
构建产物将输出到 `dist` 目录。
|
||||||
|
|
||||||
|
### 5. 预览生产构建
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn preview
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 生产部署
|
||||||
|
|
||||||
|
### 方式一:静态文件部署
|
||||||
|
|
||||||
|
1. **构建项目**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn build:prod
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **部署到 Web 服务器**
|
||||||
|
|
||||||
|
将 `dist` 目录下的所有文件上传到 Nginx、Apache 或其他 Web 服务器的根目录。
|
||||||
|
|
||||||
|
**Nginx 配置示例:**
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name your-domain.com;
|
||||||
|
root /var/www/toonflow-web/dist;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# API 代理(可选)
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://localhost:10588/;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方式二:与后端集成部署
|
||||||
|
|
||||||
|
将构建后的 `dist` 目录内容复制到后端的静态资源目录 `scripts/web` 中。
|
||||||
|
|
||||||
|
> 💡 **提示**:后端服务可从 [GitHub](https://github.com/HBAI-Ltd/Toonflow-app) 或 [Gitee](https://gitee.com/HBAI-Ltd/Toonflow-app) 仓库获取。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🔧 开发指南
|
||||||
|
|
||||||
|
## 开发环境准备
|
||||||
|
|
||||||
|
- **Node.js**:版本要求 23.11.1 及以上
|
||||||
|
- **Yarn**:推荐作为项目包管理器
|
||||||
|
|
||||||
|
## 常用命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 安装依赖
|
||||||
|
yarn install
|
||||||
|
|
||||||
|
# 启动开发服务器(支持热更新)
|
||||||
|
yarn dev
|
||||||
|
|
||||||
|
# 类型检查
|
||||||
|
yarn type-check
|
||||||
|
|
||||||
|
# 代码检查和自动修复
|
||||||
|
yarn lint
|
||||||
|
|
||||||
|
# 代码格式化
|
||||||
|
yarn format
|
||||||
|
|
||||||
|
# 构建开发版本
|
||||||
|
yarn build:dev
|
||||||
|
|
||||||
|
# 构建生产版本
|
||||||
|
yarn build:prod
|
||||||
|
|
||||||
|
# 预览生产构建
|
||||||
|
yarn preview
|
||||||
|
|
||||||
|
# 生成第三方许可证清单
|
||||||
|
yarn license
|
||||||
|
```
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
📂 Toonflow-web/
|
||||||
|
├─ 📂 public/ # 静态资源
|
||||||
|
├─ 📂 scripts/ # 构建脚本
|
||||||
|
│ └─ 📄 license.ts # 许可证生成脚本
|
||||||
|
├─ 📂 src/
|
||||||
|
│ ├─ 📂 assets/ # 静态资源(样式、图片等)
|
||||||
|
│ │ └─ 📄 main.css # 全局样式
|
||||||
|
│ ├─ 📂 components/ # 公共组件
|
||||||
|
│ │ ├─ 📄 sider.vue # 侧边栏组件
|
||||||
|
│ │ ├─ 📂 chat/ # 聊天组件
|
||||||
|
│ │ ├─ 📂 storyboardEditor/ # 分镜编辑器
|
||||||
|
│ │ └─ 📂 videoConfig/ # 视频配置组件
|
||||||
|
│ ├─ 📂 config/ # 配置文件
|
||||||
|
│ │ └─ 📄 manufacturerConfig.ts # 厂商配置
|
||||||
|
│ ├─ 📂 pages/ # 页面组件
|
||||||
|
│ │ ├─ 📂 error/ # 错误页面
|
||||||
|
│ │ ├─ 📂 login/ # 登录页面
|
||||||
|
│ │ └─ 📂 workbench/ # 工作台
|
||||||
|
│ ├─ 📂 router/ # 路由配置
|
||||||
|
│ │ └─ 📄 index.ts # 路由定义
|
||||||
|
│ ├─ 📂 stores/ # Pinia 状态管理
|
||||||
|
│ │ ├─ 📄 index.ts # Store 入口
|
||||||
|
│ │ ├─ 📄 loadingStore.ts # 加载状态
|
||||||
|
│ │ ├─ 📄 user.ts # 用户状态
|
||||||
|
│ │ └─ 📄 video.ts # 视频状态
|
||||||
|
│ ├─ 📂 types/ # TypeScript 类型定义
|
||||||
|
│ │ ├─ 📄 auto-imports.d.ts # 自动导入类型
|
||||||
|
│ │ ├─ 📄 components.d.ts # 组件类型
|
||||||
|
│ │ ├─ 📄 global.d.ts # 全局类型
|
||||||
|
│ │ ├─ 📄 manufacturer.ts # 厂商类型
|
||||||
|
│ │ └─ 📄 shims-vue.d.ts # Vue 模块声明
|
||||||
|
│ ├─ 📂 utils/ # 工具函数
|
||||||
|
│ │ ├─ 📄 axios.ts # HTTP 请求封装
|
||||||
|
│ │ ├─ 📄 combineImages.ts # 图片合成
|
||||||
|
│ │ ├─ 📄 error.ts # 错误处理
|
||||||
|
│ │ ├─ 📄 parseNovel.ts # 小说解析
|
||||||
|
│ │ ├─ 📄 splitGraph.ts # 图像分割
|
||||||
|
│ │ ├─ 📄 throttle.ts # 节流防抖
|
||||||
|
│ │ └─ 📄 wsClient.ts # WebSocket 客户端
|
||||||
|
│ ├─ 📂 views/ # 视图页面
|
||||||
|
│ │ ├─ 📂 project/ # 项目管理
|
||||||
|
│ │ ├─ 📂 projectDetail/ # 项目详情
|
||||||
|
│ │ │ ├─ 📂 components/
|
||||||
|
│ │ │ │ ├─ 📂 assetsManager/ # 素材管理
|
||||||
|
│ │ │ │ ├─ 📂 originalText/ # 原始文本
|
||||||
|
│ │ │ │ ├─ 📂 outlineManager/ # 大纲管理
|
||||||
|
│ │ │ │ ├─ 📂 overview/ # 项目概览
|
||||||
|
│ │ │ │ └─ 📂 scriptManager/ # 剧本管理
|
||||||
|
│ │ ├─ 📂 setting/ # 系统设置
|
||||||
|
│ │ └─ 📂 taskList/ # 任务列表
|
||||||
|
│ ├─ 📄 App.vue # 根组件
|
||||||
|
│ └─ 📄 main.ts # 应用入口
|
||||||
|
├─ 📄 components.d.ts # 全局组件类型
|
||||||
|
├─ 📄 eslint.config.js # ESLint 配置
|
||||||
|
├─ 📄 index.html # HTML 模板
|
||||||
|
├─ 📄 package.json # 项目配置
|
||||||
|
├─ 📄 tsconfig.json # TypeScript 配置
|
||||||
|
├─ 📄 tsconfig.app.json # 应用 TS 配置
|
||||||
|
├─ 📄 tsconfig.node.json # Node TS 配置
|
||||||
|
├─ 📄 vite.config.ts # Vite 配置
|
||||||
|
├─ 📄 LICENSE # 许可证
|
||||||
|
├─ 📄 NOTICES.txt # 第三方依赖声明
|
||||||
|
└─ 📄 README.md # 项目说明
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 📝 开发计划
|
||||||
|
|
||||||
|
我们正持续优化前端体验,以下为近期开发重点:
|
||||||
|
|
||||||
|
1. **UI/UX 优化**
|
||||||
|
- `🎨 暗色主题支持` 提供优雅的暗色模式选项,保护用户视力
|
||||||
|
- `📱 响应式布局` 优化移动端和平板设备的显示效果
|
||||||
|
- `⌨️ 快捷键系统` 添加常用操作的快捷键,提升操作效率
|
||||||
|
|
||||||
|
2. **功能增强**
|
||||||
|
- `📊 数据可视化` 增强项目数据统计和可视化图表展示
|
||||||
|
- `🔄 实时协作` 支持多人同时编辑,实时同步状态
|
||||||
|
- `💾 自动保存` 智能自动保存功能,防止数据丢失
|
||||||
|
|
||||||
|
3. **性能优化**
|
||||||
|
- `⚡ 虚拟滚动` 大数据列表的性能优化
|
||||||
|
- `🗜️ 资源压缩` 优化构建产物体积,提升加载速度
|
||||||
|
- `🔌 懒加载优化` 进一步优化路由和组件的懒加载策略
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🐛 常见问题
|
||||||
|
|
||||||
|
### Q: 启动开发服务器时端口被占用?
|
||||||
|
|
||||||
|
**A:** 修改 `vite.config.ts` 中的端口配置:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export default defineConfig({
|
||||||
|
server: {
|
||||||
|
port: 3000, // 修改为其他端口
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q: 如何配置后端 API 地址?
|
||||||
|
|
||||||
|
**A:** 在 `.env.dev` 中配置后端地址:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
VITE_TYPE=dev
|
||||||
|
VITE_BASE_URL=http://127.0.0.1:10588
|
||||||
|
VITE_WS_URL=ws://127.0.0.1:10588
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q: 我只想使用 Toonflow,不需要开发,怎么办?
|
||||||
|
|
||||||
|
**A:** 请前往主仓库下载完整客户端:
|
||||||
|
|
||||||
|
- **GitHub**:👉 [Toonflow-app](https://github.com/HBAI-Ltd/Toonflow-app)
|
||||||
|
- **Gitee**:👉 [Toonflow-app](https://gitee.com/HBAI-Ltd/Toonflow-app)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🔗 相关仓库
|
||||||
|
|
||||||
|
| 仓库 | 说明 | GitHub | Gitee |
|
||||||
|
| ---------------- | -------------------------------- | -------------------------------------------------- | ------------------------------------------------ |
|
||||||
|
| **Toonflow-app** | 完整客户端(推荐普通用户) | [GitHub](https://github.com/HBAI-Ltd/Toonflow-app) | [Gitee](https://gitee.com/HBAI-Ltd/Toonflow-app) |
|
||||||
|
| **Toonflow-web** | 前端源代码(本仓库,适合开发者) | [GitHub](https://github.com/HBAI-Ltd/Toonflow-web) | [Gitee](https://gitee.com/HBAI-Ltd/Toonflow-web) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 👨👩👧👦 微信交流群
|
||||||
|
|
||||||
|
请到主仓库中查看
|
||||||
|
|
||||||
|
- **GitHub**:👉 [Toonflow-app](https://github.com/HBAI-Ltd/Toonflow-app)
|
||||||
|
- **Gitee**:👉 [Toonflow-app](https://gitee.com/HBAI-Ltd/Toonflow-app)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 💌 联系我们
|
||||||
|
|
||||||
|
📧 邮箱:[ltlctools@outlook.com](mailto:ltlctools@outlook.com?subject=Toonflow前端咨询)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 📜 许可证
|
||||||
|
|
||||||
|
Toonflow 基于 Apache-2.0 协议开源发布,并附有补充商业协议。
|
||||||
|
|
||||||
|
许可证详情:https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
## 补充协议
|
||||||
|
|
||||||
|
- 若将本软件以产品形式分发给 **2 个及以上独立第三方**使用,须取得 HBAI-Ltd **书面商业授权**。
|
||||||
|
- **≤ 5 个法人**联合运营内部使用,不对外提供服务的,视为内部使用,**无需授权**。
|
||||||
|
- 不得删除或修改 Toonflow 中的标识或版权信息。
|
||||||
|
|
||||||
|
## 永久免费场景
|
||||||
|
|
||||||
|
- ✅ 用 Toonflow 制作内容并获得平台分账
|
||||||
|
- ✅ 二次开发供自己团队内部使用
|
||||||
|
- ✅ ≤ 5 个法人联合运营内部使用
|
||||||
|
- ✅ 个人学习、研究、非商业用途
|
||||||
|
|
||||||
|
## 商业授权定价
|
||||||
|
|
||||||
|
| 阶段 | 年销售额 | 年费 |
|
||||||
|
|------|---------|------|
|
||||||
|
| 🌱 扶持期 | < ¥10 万 | **申请即可免费授权** |
|
||||||
|
| 🚀 初创期 | ¥10–50 万 | ¥5,000/年 |
|
||||||
|
| 📈 成长期 | ¥50–150 万 | ¥20,000/年 |
|
||||||
|
| 🏢 规模期 | ¥150–500 万 | ¥80,000/年 |
|
||||||
|
| 🌐 企业级 | > ¥500 万 | 面议 |
|
||||||
|
|
||||||
|
> **不追溯条款**:v1.0.8 发布前基于 AGPL-3.0 使用的用户,继续按 AGPL-3.0 执行,不受本协议变更约束。
|
||||||
|
|
||||||
|
完整协议详见 [LICENSE](./LICENSE) 文件。
|
||||||
|
---
|
||||||
|
|
||||||
|
# ⭐️ 星标历史
|
||||||
|
|
||||||
|
[](https://www.star-history.com/#HBAI-Ltd/Toonflow-web&type=date&legend=top-left)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🙏 致谢
|
||||||
|
|
||||||
|
感谢以下开源项目为 Toonflow Web 提供强大支持:
|
||||||
|
|
||||||
|
- [Vue.js](https://vuejs.org/) - 渐进式 JavaScript 框架
|
||||||
|
- [Vite](https://vitejs.dev/) - 下一代前端构建工具
|
||||||
|
- [Ant Design Vue](https://antdv.com/) - 企业级 UI 组件库
|
||||||
|
- [Element Plus](https://element-plus.org/) - 基于 Vue 3 的组件库
|
||||||
|
- [TDesign](https://element-plus.org/) - 为设计师 & 开发者,打造工作美学
|
||||||
|
- [Pinia](https://pinia.vuejs.org/) - Vue 的直观状态管理库
|
||||||
|
|
||||||
|
感谢以下组织/单位/个人为 Toonflow 提供支持:
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<img src="./docs/sponsored/sophnet.png" alt="算能云 Logo" width="48">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<b>算能云</b> 提供算力赞助
|
||||||
|
<a href="https://www.sophnet.com/">[官网]</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
完整的第三方依赖清单请查阅 `NOTICES.txt`
|
||||||
|
|
||||||
|
##### copyright © 北京爱阿科技有限公司
|
||||||
54
web-core/components.d.ts
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
// biome-ignore lint: disable
|
||||||
|
// oxlint-disable
|
||||||
|
// ------
|
||||||
|
// Generated by unplugin-vue-components
|
||||||
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
|
|
||||||
|
export {};
|
||||||
|
|
||||||
|
/* prettier-ignore */
|
||||||
|
declare module 'vue' {
|
||||||
|
export interface GlobalComponents {
|
||||||
|
AButton: typeof import('ant-design-vue/es')['Button']
|
||||||
|
ACheckableTag: typeof import('ant-design-vue/es')['CheckableTag']
|
||||||
|
ACollapse: typeof import('ant-design-vue/es')['Collapse']
|
||||||
|
ACollapsePanel: typeof import('ant-design-vue/es')['CollapsePanel']
|
||||||
|
ADivider: typeof import('ant-design-vue/es')['Divider']
|
||||||
|
AImage: typeof import('ant-design-vue/es')['Image']
|
||||||
|
AInput: typeof import('ant-design-vue/es')['Input']
|
||||||
|
AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
|
||||||
|
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
||||||
|
ALayout: typeof import('ant-design-vue/es')['Layout']
|
||||||
|
ALayoutContent: typeof import('ant-design-vue/es')['LayoutContent']
|
||||||
|
ALayoutSider: typeof import('ant-design-vue/es')['LayoutSider']
|
||||||
|
AModal: typeof import('ant-design-vue/es')['Modal']
|
||||||
|
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
||||||
|
AProgress: typeof import('ant-design-vue/es')['Progress']
|
||||||
|
ARadio: typeof import('ant-design-vue/es')['Radio']
|
||||||
|
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
|
||||||
|
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||||
|
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
||||||
|
ASpin: typeof import('ant-design-vue/es')['Spin']
|
||||||
|
ASteps: typeof import('ant-design-vue/es')['Steps']
|
||||||
|
ATag: typeof import('ant-design-vue/es')['Tag']
|
||||||
|
ATextarea: typeof import('ant-design-vue/es')['Textarea']
|
||||||
|
AUpload: typeof import('ant-design-vue/es')['Upload']
|
||||||
|
AUploadDragger: typeof import('ant-design-vue/es')['UploadDragger']
|
||||||
|
BlurReveal: typeof import('./src/components/BlurReveal.vue')['default']
|
||||||
|
Book: typeof import('./src/components/book/Book.vue')['default']
|
||||||
|
BookDescription: typeof import('./src/components/book/BookDescription.vue')['default']
|
||||||
|
BookHeader: typeof import('./src/components/book/BookHeader.vue')['default']
|
||||||
|
BookTitle: typeof import('./src/components/book/BookTitle.vue')['default']
|
||||||
|
ColourfulText: typeof import('./src/components/ColourfulText.vue')['default']
|
||||||
|
FileUpload: typeof import('./src/components/fileUpload/FileUpload.vue')['default']
|
||||||
|
FileUploadGrid: typeof import('./src/components/fileUpload/FileUploadGrid.vue')['default']
|
||||||
|
MultiStepLoader: typeof import('./src/components/MultiStepLoader.vue')['default']
|
||||||
|
NewAndEdit: typeof import('./src/components/newAndEdit/index.vue')['default']
|
||||||
|
RainbowButton: typeof import('./src/components/RainbowButton.vue')['default']
|
||||||
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
Sider: typeof import('./src/components/sider.vue')['default']
|
||||||
|
}
|
||||||
|
}
|
||||||
470
web-core/docs/README.en.md
Normal file
@ -0,0 +1,470 @@
|
|||||||
|
<p align="center">
|
||||||
|
<a href="../README.md">中文</a> |
|
||||||
|
<strong>English</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
<img src="./logo.png" alt="Toonflow Logo" height="120"/>
|
||||||
|
|
||||||
|
# Toonflow Web
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<b>
|
||||||
|
Toonflow Frontend Application
|
||||||
|
<br />
|
||||||
|
Modern Web interface built with Vue 3 + TypeScript + Vite
|
||||||
|
<br />
|
||||||
|
User frontend for AI Short Drama Factory 🎨
|
||||||
|
</b>
|
||||||
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/HBAI-Ltd/Toonflow-web/stargazers">
|
||||||
|
<img src="https://img.shields.io/github/stars/HBAI-Ltd/Toonflow-web?style=for-the-badge&logo=github" alt="Stars Badge" />
|
||||||
|
</a>
|
||||||
|
<a href="https://www.gnu.org/licenses/agpl-3.0" target="_blank">
|
||||||
|
<img src="https://img.shields.io/badge/License-AGPL-blue.svg?style=for-the-badge" alt="AGPL License Badge" />
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/HBAI-Ltd/Toonflow-web/releases">
|
||||||
|
<img alt="release" src="https://img.shields.io/github/v/release/HBAI-Ltd/Toonflow-web?style=for-the-badge" />
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
> 🎯 **Modern Frontend Architecture**: Built with Vue 3 Composition API, TypeScript type safety, and Vite for lightning-fast builds, delivering a smooth user experience!
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# ⚠️ Important Notice
|
||||||
|
|
||||||
|
> **This repository only contains the frontend source code, suitable for developers for secondary development or customization.**
|
||||||
|
>
|
||||||
|
> 🎉 **If you are a regular user wishing to use Toonflow directly, please go to the main repository to download the full client:**
|
||||||
|
>
|
||||||
|
> | Platform | Link |
|
||||||
|
> | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- |
|
||||||
|
> | <img src="https://img.shields.io/badge/GitHub-181717?style=flat&logo=github&logoColor=white" alt="GitHub" /> | 👉 [github.com/HBAI-Ltd/Toonflow-app](https://github.com/HBAI-Ltd/Toonflow-app) |
|
||||||
|
> | <img src="https://img.shields.io/badge/Gitee-C71D23?style=flat&logo=gitee&logoColor=white" alt="Gitee" /> | 👉 [gitee.com/HBAI-Ltd/Toonflow-app](https://gitee.com/HBAI-Ltd/Toonflow-app) |
|
||||||
|
>
|
||||||
|
> The main repository includes:
|
||||||
|
>
|
||||||
|
> - ✅ Complete desktop client
|
||||||
|
> - ✅ Backend service
|
||||||
|
> - ✅ Ready-to-use installer
|
||||||
|
> - ✅ Detailed usage tutorial
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🌟 Tech Stack
|
||||||
|
|
||||||
|
- **Framework**: Vue 3.5+ (Composition API)
|
||||||
|
- **Build Tool**: Vite 5.4+
|
||||||
|
- **Language**: TypeScript 5.6+
|
||||||
|
- **State Management**: Pinia 2.2+ (supports persistence)
|
||||||
|
- **Routing**: Vue Router 4.4+
|
||||||
|
- **UI Component Libraries**:
|
||||||
|
- Ant Design Vue 4.2+
|
||||||
|
- Element Plus 2.13+
|
||||||
|
- VXE Table 4.17+
|
||||||
|
- **Utility Libraries**:
|
||||||
|
- Axios - HTTP requests
|
||||||
|
- VueUse - Vue composition utilities
|
||||||
|
- Day.js - Date handling
|
||||||
|
- Mammoth - Word document parsing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🎨 Main Feature Modules
|
||||||
|
|
||||||
|
Toonflow Web provides a complete frontend for short drama creation, including these core modules:
|
||||||
|
|
||||||
|
- ✅ **Project Management**
|
||||||
|
Create, edit, and manage drama projects with project status tracking and multi-project parallel development.
|
||||||
|
|
||||||
|
- ✅ **Raw Text Editing**
|
||||||
|
Import and edit novel manuscripts, supports Word document parsing, intelligent text cleansing, and chapter splitting.
|
||||||
|
|
||||||
|
- ✅ **Character Asset Library**
|
||||||
|
Manage character settings and images; supports batch generation, manual upload, and online editing.
|
||||||
|
|
||||||
|
- ✅ **Outline Management**
|
||||||
|
Visual editing of story outlines and event lines, with drag-and-drop sorting and smart generation.
|
||||||
|
|
||||||
|
- ✅ **Script Editor**
|
||||||
|
Structured script editing interface, supports labeling dialogues, scenes, emotions, and more dimensions.
|
||||||
|
|
||||||
|
- ✅ **Storyboard Design**
|
||||||
|
Visual storyboard canvas with drag-and-drop layout, image detection, and AI conversational storyboard generation.
|
||||||
|
|
||||||
|
- ✅ **Video Configuration**
|
||||||
|
Configure video generation parameters, support switching among multiple AI video providers, and video downloading.
|
||||||
|
|
||||||
|
- ✅ **Task Monitoring**
|
||||||
|
Real-time monitoring of AI generation tasks, supports task queue management and history search.
|
||||||
|
|
||||||
|
- ✅ **System Settings**
|
||||||
|
Configure AI providers, prompt templates, user permissions, and other system-level parameters.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 📦 Application Scenarios
|
||||||
|
|
||||||
|
- Frontend operation interface for short drama content creation
|
||||||
|
- Visual platform for AI-assisted screenwriting tools
|
||||||
|
- Workbench for storyboard design and video generation
|
||||||
|
- Scenario management system for multi-user collaboration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🚀 Getting Started Quickly
|
||||||
|
|
||||||
|
## 💡 What kind of user are you?
|
||||||
|
|
||||||
|
| User Type | Recommended Solution | GitHub | Gitee |
|
||||||
|
| ------------------------------------------- | -------------------- | -------------------------------------------------------- | ------------------------------------------------------- |
|
||||||
|
| 🎬 **Regular User** - Want to use Toonflow | Download full client | [Toonflow-app](https://github.com/HBAI-Ltd/Toonflow-app) | [Toonflow-app](https://gitee.com/HBAI-Ltd/Toonflow-app) |
|
||||||
|
| 👨💻 **Developer** - Want to modify or extend | Continue reading | This repository | This repository |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
Before developing and running this project, please ensure you have installed:
|
||||||
|
|
||||||
|
- ✅ **Node.js**: version 23.11.1 or above
|
||||||
|
- ✅ **Yarn**: version 1.22.0 or above (recommended package manager)
|
||||||
|
- ✅ **Backend service**: Make sure the Toonflow backend service is running and accessible (available from [GitHub](https://github.com/HBAI-Ltd/Toonflow-app) or [Gitee](https://gitee.com/HBAI-Ltd/Toonflow-app))
|
||||||
|
|
||||||
|
## Local Development
|
||||||
|
|
||||||
|
### 1. Clone the Project
|
||||||
|
|
||||||
|
**GitHub:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/HBAI-Ltd/Toonflow-web.git
|
||||||
|
cd Toonflow-web
|
||||||
|
```
|
||||||
|
|
||||||
|
**Gitee (recommended for China):**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://gitee.com/HBAI-Ltd/Toonflow-web.git
|
||||||
|
cd Toonflow-web
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Install Dependencies
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn install
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Start the Development Server
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn dev
|
||||||
|
```
|
||||||
|
|
||||||
|
The dev server runs at `http://localhost:5173` by default, with hot module replacement (HMR) enabled.
|
||||||
|
|
||||||
|
### 4. Build for Production
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Development build
|
||||||
|
yarn build:dev
|
||||||
|
|
||||||
|
# Production build
|
||||||
|
yarn build:prod
|
||||||
|
```
|
||||||
|
|
||||||
|
The build output will be in the `dist` directory.
|
||||||
|
|
||||||
|
### 5. Preview Production Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn preview
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Production Deployment
|
||||||
|
|
||||||
|
### Method 1: Static File Deployment
|
||||||
|
|
||||||
|
1. **Build the Project**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn build:prod
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Deploy to Web Server**
|
||||||
|
|
||||||
|
Upload all files in the `dist` directory to the root directory of Nginx, Apache, or any other web server.
|
||||||
|
|
||||||
|
**Sample Nginx configuration:**
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name your-domain.com;
|
||||||
|
root /var/www/toonflow-web/dist;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# API Proxy (optional)
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://localhost:10588/;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Method 2: Integrated deployment with backend
|
||||||
|
|
||||||
|
Copy the contents of the built `dist` directory into the backend's static resources directory `scripts/web`.
|
||||||
|
|
||||||
|
> 💡 **Note**: The backend service can be obtained from [GitHub](https://github.com/HBAI-Ltd/Toonflow-app) or [Gitee](https://gitee.com/HBAI-Ltd/Toonflow-app).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🔧 Development Guide
|
||||||
|
|
||||||
|
## Prepare Development Environment
|
||||||
|
|
||||||
|
- **Node.js**: version 23.11.1 or above required
|
||||||
|
- **Yarn**: recommended package manager
|
||||||
|
|
||||||
|
## Common Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install dependencies
|
||||||
|
yarn install
|
||||||
|
|
||||||
|
# Start development server (supports hot reload)
|
||||||
|
yarn dev
|
||||||
|
|
||||||
|
# Type checking
|
||||||
|
yarn type-check
|
||||||
|
|
||||||
|
# Code linting and auto-fix
|
||||||
|
yarn lint
|
||||||
|
|
||||||
|
# Code formatting
|
||||||
|
yarn format
|
||||||
|
|
||||||
|
# Development build
|
||||||
|
yarn build:dev
|
||||||
|
|
||||||
|
# Production build
|
||||||
|
yarn build:prod
|
||||||
|
|
||||||
|
# Preview production build
|
||||||
|
yarn preview
|
||||||
|
|
||||||
|
# Generate third-party license list
|
||||||
|
yarn license
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
📂 Toonflow-web/
|
||||||
|
├─ 📂 public/ # Static assets
|
||||||
|
├─ 📂 scripts/ # Build scripts
|
||||||
|
│ └─ 📄 license.ts # License generator script
|
||||||
|
├─ 📂 src/
|
||||||
|
│ ├─ 📂 assets/ # Static assets (styles, images, etc.)
|
||||||
|
│ │ └─ 📄 main.css # Global styles
|
||||||
|
│ ├─ 📂 components/ # Common components
|
||||||
|
│ │ ├─ 📄 sider.vue # Sidebar component
|
||||||
|
│ │ ├─ 📂 chat/ # Chat components
|
||||||
|
│ │ ├─ 📂 storyboardEditor/ # Storyboard editor
|
||||||
|
│ │ └─ 📂 videoConfig/ # Video config components
|
||||||
|
│ ├─ 📂 config/ # Configuration files
|
||||||
|
│ │ └─ 📄 manufacturerConfig.ts # Manufacturer configuration
|
||||||
|
│ ├─ 📂 pages/ # Page components
|
||||||
|
│ │ ├─ 📂 error/ # Error pages
|
||||||
|
│ │ ├─ 📂 login/ # Login page
|
||||||
|
│ │ └─ 📂 workbench/ # Workbench
|
||||||
|
│ ├─ 📂 router/ # Routing configuration
|
||||||
|
│ │ └─ 📄 index.ts # Route definitions
|
||||||
|
│ ├─ 📂 stores/ # Pinia state management
|
||||||
|
│ │ ├─ 📄 index.ts # Store entry
|
||||||
|
│ │ ├─ 📄 loadingStore.ts # Loading state
|
||||||
|
│ │ ├─ 📄 user.ts # User state
|
||||||
|
│ │ └─ 📄 video.ts # Video state
|
||||||
|
│ ├─ 📂 types/ # TypeScript type definitions
|
||||||
|
│ │ ├─ 📄 auto-imports.d.ts # Auto-imported types
|
||||||
|
│ │ ├─ 📄 components.d.ts # Component types
|
||||||
|
│ │ ├─ 📄 global.d.ts # Global types
|
||||||
|
│ │ ├─ 📄 manufacturer.ts # Manufacturer types
|
||||||
|
│ │ └─ 📄 shims-vue.d.ts # Vue module declarations
|
||||||
|
│ ├─ 📂 utils/ # Utility functions
|
||||||
|
│ │ ├─ 📄 axios.ts # HTTP request wrapper
|
||||||
|
│ │ ├─ 📄 combineImages.ts # Image composition
|
||||||
|
│ │ ├─ 📄 error.ts # Error handling
|
||||||
|
│ │ ├─ 📄 parseNovel.ts # Novel parsing
|
||||||
|
│ │ ├─ 📄 splitGraph.ts # Image segmentation
|
||||||
|
│ │ ├─ 📄 throttle.ts # Throttling/debouncing
|
||||||
|
│ │ └─ 📄 wsClient.ts # WebSocket client
|
||||||
|
│ ├─ 📂 views/ # View pages
|
||||||
|
│ │ ├─ 📂 project/ # Project management
|
||||||
|
│ │ ├─ 📂 projectDetail/ # Project details
|
||||||
|
│ │ │ ├─ 📂 components/
|
||||||
|
│ │ │ │ ├─ 📂 assetsManager/ # Asset management
|
||||||
|
│ │ │ │ ├─ 📂 originalText/ # Raw text
|
||||||
|
│ │ │ │ ├─ 📂 outlineManager/ # Outline management
|
||||||
|
│ │ │ │ ├─ 📂 overview/ # Project overview
|
||||||
|
│ │ │ │ └─ 📂 scriptManager/ # Script management
|
||||||
|
│ │ ├─ 📂 setting/ # System settings
|
||||||
|
│ │ └─ 📂 taskList/ # Task list
|
||||||
|
│ ├─ 📄 App.vue # Root component
|
||||||
|
│ └─ 📄 main.ts # App entry point
|
||||||
|
├─ 📄 components.d.ts # Global component types
|
||||||
|
├─ 📄 eslint.config.js # ESLint config
|
||||||
|
├─ 📄 index.html # HTML template
|
||||||
|
├─ 📄 package.json # Project config
|
||||||
|
├─ 📄 tsconfig.json # TypeScript config
|
||||||
|
├─ 📄 tsconfig.app.json # App TS config
|
||||||
|
├─ 📄 tsconfig.node.json # Node TS config
|
||||||
|
├─ 📄 vite.config.ts # Vite config
|
||||||
|
├─ 📄 LICENSE # License
|
||||||
|
├─ 📄 NOTICES.txt # Third-party notices
|
||||||
|
└─ 📄 README.md # Project documentation
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 📝 Development Plan
|
||||||
|
|
||||||
|
We are continuously optimizing the frontend experience. Key development focuses in the near future:
|
||||||
|
|
||||||
|
1. **UI/UX Optimization**
|
||||||
|
- `🎨 Dark theme support` Elegant dark mode option to protect eyesight
|
||||||
|
- `📱 Responsive layout` Improved display for mobile and tablet devices
|
||||||
|
- `⌨️ Shortcut system` Adding shortcuts for common operations to improve efficiency
|
||||||
|
|
||||||
|
2. **Feature Enhancements**
|
||||||
|
- `📊 Data visualization` Advanced project statistics and chart displays
|
||||||
|
- `🔄 Real-time collaboration` Multi-user simultaneous editing and real-time sync
|
||||||
|
- `💾 Auto-save` Smart auto-save to prevent data loss
|
||||||
|
|
||||||
|
3. **Performance Optimization**
|
||||||
|
- `⚡ Virtual scrolling` High-performance optimization for large lists
|
||||||
|
- `🗜️ Asset compression` Optimizing build size for faster loading
|
||||||
|
- `🔌 Lazy loading optimization` Further optimize route and component lazy loading strategy
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🐛 FAQ
|
||||||
|
|
||||||
|
### Q: Port is occupied when starting dev server?
|
||||||
|
|
||||||
|
**A:** Modify the port configuration in `vite.config.ts`:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export default defineConfig({
|
||||||
|
server: {
|
||||||
|
port: 3000, // change to another port
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q: How to configure the backend API address?
|
||||||
|
|
||||||
|
**A:** Set the backend address in `.env.dev`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
VITE_TYPE=dev
|
||||||
|
VITE_BASE_URL=http://127.0.0.1:10588
|
||||||
|
VITE_WS_URL=ws://127.0.0.1:10588
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q: I just want to use Toonflow, not develop, what should I do?
|
||||||
|
|
||||||
|
**A:** Please go to the main repository to download the complete client:
|
||||||
|
|
||||||
|
- **GitHub**: 👉 [Toonflow-app](https://github.com/HBAI-Ltd/Toonflow-app)
|
||||||
|
- **Gitee**: 👉 [Toonflow-app](https://gitee.com/HBAI-Ltd/Toonflow-app)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🔗 Related Repositories
|
||||||
|
|
||||||
|
| Repository | Description | GitHub | Gitee |
|
||||||
|
| ---------------- | ---------------------------------- | -------------------------------------------------- | ------------------------------------------------ |
|
||||||
|
| **Toonflow-app** | Complete client (recommended user) | [GitHub](https://github.com/HBAI-Ltd/Toonflow-app) | [Gitee](https://gitee.com/HBAI-Ltd/Toonflow-app) |
|
||||||
|
| **Toonflow-web** | Frontend source code (this repo) | [GitHub](https://github.com/HBAI-Ltd/Toonflow-web) | [Gitee](https://gitee.com/HBAI-Ltd/Toonflow-web) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 👨👩👧👦 WeChat Community Group
|
||||||
|
|
||||||
|
~~Group 1~~
|
||||||
|
|
||||||
|
~~Group 2~~
|
||||||
|
|
||||||
|
~~Group 3~~
|
||||||
|
|
||||||
|
~~Group 4~~
|
||||||
|
|
||||||
|
~~Group 5~~
|
||||||
|
|
||||||
|
Group 6:
|
||||||
|
|
||||||
|
<img src="./chat6QR.jpg" alt="Toonflow Logo" height="400"/>
|
||||||
|
<p>Scan with WeChat to add. If the QR code expires, submit an Issue for update.</p>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 💌 Contact Us
|
||||||
|
|
||||||
|
📧 Email: [ltlctools@outlook.com](mailto:ltlctools@outlook.com?subject=Toonflow%20Frontend%20Consultation)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 📜 License
|
||||||
|
|
||||||
|
Toonflow Web is open-sourced under the AGPL-3.0 license. See details: https://www.gnu.org/licenses/agpl-3.0.html
|
||||||
|
|
||||||
|
You may use Toonflow Web for any purposes, including commercial, as long as you comply with the AGPL-3.0 terms and conditions.
|
||||||
|
|
||||||
|
If you wish to obtain a proprietary commercial license free from AGPL-3.0 restrictions, please contact us via email.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# ⭐️ Star History
|
||||||
|
|
||||||
|
[](https://www.star-history.com/#HBAI-Ltd/Toonflow-web&type=date&legend=top-left)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🙏 Acknowledgements
|
||||||
|
|
||||||
|
Thanks to the following open source projects for their strong support for Toonflow Web:
|
||||||
|
|
||||||
|
- [Vue.js](https://vuejs.org/) - Progressive JavaScript framework
|
||||||
|
- [Vite](https://vitejs.dev/) - Next generation frontend build tool
|
||||||
|
- [Ant Design Vue](https://antdv.com/) - Enterprise-level UI component library
|
||||||
|
- [Element Plus](https://element-plus.org/) - Vue 3-based component library
|
||||||
|
- [Pinia](https://pinia.vuejs.org/) - Intuitive state management library for Vue
|
||||||
|
|
||||||
|
Thanks to the following organizations/units/individuals for supporting Toonflow:
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<img src="./sponsored/sophnet.png" alt="Suan Neng Yun Logo" width="48">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<b>Suan Neng Yun</b> provides compute sponsorship
|
||||||
|
<a href="https://www.sophnet.com/">[Official Site]</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
For a complete list of third-party dependencies, please refer to `NOTICES.txt`
|
||||||
BIN
web-core/docs/logo.png
Normal file
|
After Width: | Height: | Size: 196 KiB |
BIN
web-core/docs/sponsored/sophnet.png
Normal file
|
After Width: | Height: | Size: 758 B |
BIN
web-core/docs/videoCover.png
Normal file
|
After Width: | Height: | Size: 101 KiB |
BIN
web-core/docs/videoQR.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
13
web-core/index.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Toonflow</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
67
web-core/package.json
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
{
|
||||||
|
"name": "toonflow_web",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite --host",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"build": "vue-tsc --build --force && vite build",
|
||||||
|
"build-only": "vite build",
|
||||||
|
"type-check": "vue-tsc --build --force",
|
||||||
|
"license": "node scripts/license.ts",
|
||||||
|
"i18n:check": "node scripts/findUnusedI18n.ts"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@dagrejs/dagre": "^3.0.0",
|
||||||
|
"@devui-design/icons": "^1.4.0",
|
||||||
|
"@icon-park/vue-next": "^1.4.2",
|
||||||
|
"@tdesign-vue-next/chat": "^0.5.1",
|
||||||
|
"@vue-flow/background": "^1.3.2",
|
||||||
|
"@vue-flow/controls": "^1.1.3",
|
||||||
|
"@vue-flow/core": "^1.48.2",
|
||||||
|
"@vueuse/core": "^14.1.0",
|
||||||
|
"@webav/av-canvas": "^1.2.8",
|
||||||
|
"@webav/av-cliper": "^1.2.8",
|
||||||
|
"axios": "^1.13.2",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
|
"dayjs": "^1.11.19",
|
||||||
|
"js-confetti": "^0.13.1",
|
||||||
|
"lodash": "^4.17.23",
|
||||||
|
"mammoth": "^1.12.0",
|
||||||
|
"md-editor-v3": "^6.4.0",
|
||||||
|
"monaco-editor": "^0.55.1",
|
||||||
|
"monaco-editor-vue3": "^1.0.5",
|
||||||
|
"p-limit": "^7.3.0",
|
||||||
|
"pinia": "^2.2.6",
|
||||||
|
"pinia-plugin-persistedstate": "^4.7.1",
|
||||||
|
"sass": "^1.97.0",
|
||||||
|
"socket.io-client": "^4.8.3",
|
||||||
|
"splitpanes": "^4.0.4",
|
||||||
|
"tdesign-vue-next": "^1.18.5",
|
||||||
|
"uuid": "^13.0.0",
|
||||||
|
"vue": "^3.5.12",
|
||||||
|
"vue-clip-track": "^0.1.5",
|
||||||
|
"vue-draggable-plus": "^0.6.1",
|
||||||
|
"vue-i18n": "11",
|
||||||
|
"vue-router": "^4.4.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@tdesign-vue-next/auto-import-resolver": "^0.1.6",
|
||||||
|
"@tsconfig/node22": "^22.0.0",
|
||||||
|
"@types/license-checker": "^25.0.6",
|
||||||
|
"@types/node": "^22.9.0",
|
||||||
|
"@types/splitpanes": "^2.2.6",
|
||||||
|
"@types/uuid": "^11.0.0",
|
||||||
|
"@vitejs/plugin-vue": "^6.0.5",
|
||||||
|
"@vue/tsconfig": "^0.5.1",
|
||||||
|
"license-checker": "^25.0.1",
|
||||||
|
"postcss-px-to-viewport": "^1.1.1",
|
||||||
|
"prettier": "^3.3.3",
|
||||||
|
"typescript": "~5.6.3",
|
||||||
|
"unplugin-auto-import": "^21.0.0",
|
||||||
|
"unplugin-vue-components": "^31.0.0",
|
||||||
|
"vite": "^5.4.10",
|
||||||
|
"vite-plugin-singlefile": "^2.3.0",
|
||||||
|
"vue-tsc": "^2.1.10"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
web-core/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 169 KiB |
32
web-core/public/favicon.svg
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-label="ToonFlow logo">
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="tf-stem" x1="24" y1="24" x2="96" y2="98" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#64e1d3"/>
|
||||||
|
<stop offset="0.58" stop-color="#8ea3ff"/>
|
||||||
|
<stop offset="1" stop-color="#ffb46b"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="tf-play" x1="63" y1="42" x2="92" y2="82" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#ffffff"/>
|
||||||
|
<stop offset="1" stop-color="#dffdf7"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<rect width="128" height="128" rx="30" fill="#101828"/>
|
||||||
|
<path
|
||||||
|
fill="url(#tf-stem)"
|
||||||
|
d="M28 24h72c5.52 0 10 4.48 10 10v4c0 5.52-4.48 10-10 10H74v49c0 5.52-4.48 10-10 10H52c-5.52 0-10-4.48-10-10V48H28c-5.52 0-10-4.48-10-10v-4c0-5.52 4.48-10 10-10Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="url(#tf-stem)"
|
||||||
|
opacity=".9"
|
||||||
|
d="M42 74h56c6.63 0 12 5.37 12 12v2c0 6.63-5.37 12-12 12H42V74Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="#142133"
|
||||||
|
fill-opacity=".25"
|
||||||
|
d="M31 32h10a4 4 0 0 1 0 8H31a4 4 0 0 1 0-8Zm44 50h14a4 4 0 0 1 0 8H75a4 4 0 0 1 0-8Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="url(#tf-play)"
|
||||||
|
d="M68.4 47.58c-3.32-2.09-7.65.3-7.65 4.22v32.4c0 3.92 4.33 6.31 7.65 4.22l25.7-16.2c3.1-1.95 3.1-6.49 0-8.44l-25.7-16.2Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
311
web-core/scripts/findUnusedI18n.ts
Normal file
@ -0,0 +1,311 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
// 配置
|
||||||
|
const localesDir = './src/locales/language';
|
||||||
|
const srcDir = './src';
|
||||||
|
|
||||||
|
// 递归获取文件
|
||||||
|
function getFiles(dir: string, extensions: string[]): string[] {
|
||||||
|
const files: string[] = [];
|
||||||
|
|
||||||
|
function walk(currentDir: string): void {
|
||||||
|
const items = fs.readdirSync(currentDir, { withFileTypes: true });
|
||||||
|
|
||||||
|
for (const item of items) {
|
||||||
|
const fullPath = path.join(currentDir, item.name);
|
||||||
|
|
||||||
|
if (item.isDirectory()) {
|
||||||
|
if (!['node_modules', 'dist', '.git', 'locales'].includes(item.name)) {
|
||||||
|
walk(fullPath);
|
||||||
|
}
|
||||||
|
} else if (item.isFile()) {
|
||||||
|
const ext = path.extname(item.name);
|
||||||
|
if (extensions.includes(ext)) {
|
||||||
|
files.push(fullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
walk(dir);
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取所有 i18n key
|
||||||
|
function getAllI18nKeys(): Set<string> {
|
||||||
|
const keys = new Set<string>();
|
||||||
|
const files = getFiles(localesDir, ['.json']);
|
||||||
|
|
||||||
|
files.forEach(file => {
|
||||||
|
const content = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
||||||
|
extractKeys(content, '', keys);
|
||||||
|
});
|
||||||
|
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractKeys(obj: Record<string, unknown>, prefix: string, keys: Set<string>): void {
|
||||||
|
for (const key in obj) {
|
||||||
|
const fullKey = prefix ? `${prefix}.${key}` : key;
|
||||||
|
if (typeof obj[key] === 'object' && obj[key] !== null) {
|
||||||
|
extractKeys(obj[key] as Record<string, unknown>, fullKey, keys);
|
||||||
|
} else {
|
||||||
|
keys.add(fullKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断字符串是否像 i18n key
|
||||||
|
function looksLikeI18nKey(str: string): boolean {
|
||||||
|
if (!str.includes('.')) return false;
|
||||||
|
if (str.startsWith('http')) return false;
|
||||||
|
if (str.includes('/')) return false;
|
||||||
|
if (str.includes(' ')) return false;
|
||||||
|
if (/^\d/.test(str)) return false;
|
||||||
|
if (str.includes('@')) return false;
|
||||||
|
return /^[a-zA-Z][a-zA-Z0-9]*(\.[a-zA-Z][a-zA-Z0-9]*)+$/.test(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 扫描源码中使用的 key
|
||||||
|
function getUsedKeys(allKeys: Set<string>): Set<string> {
|
||||||
|
const used = new Set<string>();
|
||||||
|
const files = getFiles(srcDir, ['.vue', '.js', '.ts', '.jsx', '.tsx']);
|
||||||
|
|
||||||
|
const patterns = [
|
||||||
|
/\$t\s*\(\s*['"`]([^'"`]+)['"`]/g,
|
||||||
|
/\bt\s*\(\s*['"`]([^'"`]+)['"`]/g,
|
||||||
|
/i18n\.t\s*\(\s*['"`]([^'"`]+)['"`]/g,
|
||||||
|
/label:\s*['"`]([^'"`]+)['"`]/g,
|
||||||
|
/title:\s*['"`]([^'"`]+)['"`]/g,
|
||||||
|
/placeholder:\s*['"`]([^'"`]+)['"`]/g,
|
||||||
|
/message:\s*['"`]([^'"`]+)['"`]/g,
|
||||||
|
/text:\s*['"`]([^'"`]+)['"`]/g,
|
||||||
|
];
|
||||||
|
|
||||||
|
files.forEach(file => {
|
||||||
|
const content = fs.readFileSync(file, 'utf-8');
|
||||||
|
|
||||||
|
patterns.forEach(pattern => {
|
||||||
|
let match;
|
||||||
|
pattern.lastIndex = 0;
|
||||||
|
while ((match = pattern.exec(content)) !== null) {
|
||||||
|
used.add(match[1]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
allKeys.forEach(key => {
|
||||||
|
if (
|
||||||
|
content.includes(`'${key}'`) ||
|
||||||
|
content.includes(`"${key}"`) ||
|
||||||
|
content.includes(`\`${key}\``)
|
||||||
|
) {
|
||||||
|
used.add(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return used;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查 key 是否存在
|
||||||
|
function keyExists(key: string, allKeys: Set<string>): boolean {
|
||||||
|
if (allKeys.has(key)) return true;
|
||||||
|
for (const existKey of allKeys) {
|
||||||
|
if (existKey.startsWith(`${key}.`)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 硬编码文本信息
|
||||||
|
interface HardcodedText {
|
||||||
|
file: string;
|
||||||
|
line: number;
|
||||||
|
text: string;
|
||||||
|
context: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测硬编码的中英文
|
||||||
|
function findHardcodedTexts(): HardcodedText[] {
|
||||||
|
const results: HardcodedText[] = [];
|
||||||
|
const files = getFiles(srcDir, ['.vue', '.js', '.ts', '.jsx', '.tsx']);
|
||||||
|
|
||||||
|
// 中文匹配
|
||||||
|
const chinesePattern = /[\u4e00-\u9fa5]+[^'"`]*[\u4e00-\u9fa5]*/g;
|
||||||
|
|
||||||
|
// 英文短语匹配(至少两个单词,排除常见代码模式)
|
||||||
|
const englishPattern = /['"`]([A-Z][a-z]+(?:\s+[a-zA-Z]+){1,10})['"` ]/g;
|
||||||
|
|
||||||
|
// 需要忽略的模式
|
||||||
|
const ignorePatterns = [
|
||||||
|
/console\.(log|warn|error|info)/,
|
||||||
|
/\/\/.*/,
|
||||||
|
/\/\*[\s\S]*?\*\//,
|
||||||
|
/import\s+/,
|
||||||
|
/export\s+/,
|
||||||
|
/require\s*\(/,
|
||||||
|
/^\s*\*/,
|
||||||
|
/eslint-disable/,
|
||||||
|
/TODO:|FIXME:|NOTE:/,
|
||||||
|
/http[s]?:\/\//,
|
||||||
|
/\.(vue|js|ts|css|scss|json|png|jpg|svg)/,
|
||||||
|
];
|
||||||
|
|
||||||
|
// 常见的可忽略英文
|
||||||
|
const ignoreEnglishWords = new Set([
|
||||||
|
'New Tab',
|
||||||
|
'Click Me',
|
||||||
|
'Hello World',
|
||||||
|
'Vue Router',
|
||||||
|
'Event Bus',
|
||||||
|
'Local Storage',
|
||||||
|
'Session Storage',
|
||||||
|
'Content Type',
|
||||||
|
'User Agent',
|
||||||
|
'Access Control',
|
||||||
|
]);
|
||||||
|
|
||||||
|
files.forEach(filePath => {
|
||||||
|
const content = fs.readFileSync(filePath, 'utf-8');
|
||||||
|
const lines = content.split('\n');
|
||||||
|
|
||||||
|
lines.forEach((line, index) => {
|
||||||
|
// 跳过注释和导入
|
||||||
|
const shouldIgnore = ignorePatterns.some(pattern => pattern.test(line));
|
||||||
|
if (shouldIgnore) return;
|
||||||
|
|
||||||
|
// 跳过已使用 $t 或 t() 的行
|
||||||
|
if (/\$t\s*\(/.test(line) || /\bt\s*\(/.test(line)) return;
|
||||||
|
|
||||||
|
// 检测中文
|
||||||
|
const chineseMatches = line.match(chinesePattern);
|
||||||
|
if (chineseMatches) {
|
||||||
|
chineseMatches.forEach(text => {
|
||||||
|
// 过滤掉注释中的中文
|
||||||
|
if (line.trimStart().startsWith('//')) return;
|
||||||
|
if (line.trimStart().startsWith('*')) return;
|
||||||
|
|
||||||
|
// 检查是否在字符串中
|
||||||
|
const inString =
|
||||||
|
line.includes(`'${text}`) ||
|
||||||
|
line.includes(`"${text}`) ||
|
||||||
|
line.includes(`\`${text}`);
|
||||||
|
|
||||||
|
if (inString && text.length >= 2) {
|
||||||
|
results.push({
|
||||||
|
file: filePath,
|
||||||
|
line: index + 1,
|
||||||
|
text: text.trim(),
|
||||||
|
context: line.trim().slice(0, 100),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测英文短语
|
||||||
|
let match;
|
||||||
|
englishPattern.lastIndex = 0;
|
||||||
|
while ((match = englishPattern.exec(line)) !== null) {
|
||||||
|
const text = match[1];
|
||||||
|
|
||||||
|
// 过滤
|
||||||
|
if (ignoreEnglishWords.has(text)) continue;
|
||||||
|
if (text.length < 5) continue;
|
||||||
|
if (/^[A-Z_]+$/.test(text)) continue; // 常量
|
||||||
|
if (looksLikeI18nKey(text)) continue;
|
||||||
|
|
||||||
|
// 看起来像用户可见文本
|
||||||
|
if (/^[A-Z][a-z]+(\s+[a-zA-Z]+)+$/.test(text)) {
|
||||||
|
results.push({
|
||||||
|
file: filePath,
|
||||||
|
line: index + 1,
|
||||||
|
text,
|
||||||
|
context: line.trim().slice(0, 100),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 去重
|
||||||
|
const unique = new Map<string, HardcodedText>();
|
||||||
|
results.forEach(item => {
|
||||||
|
const key = `${item.file}:${item.line}:${item.text}`;
|
||||||
|
if (!unique.has(key)) {
|
||||||
|
unique.set(key, item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return [...unique.values()];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 主逻辑
|
||||||
|
function main(): void {
|
||||||
|
const allKeys = getAllI18nKeys();
|
||||||
|
const usedKeys = getUsedKeys(allKeys);
|
||||||
|
|
||||||
|
console.log(`\n📊 总 key 数量: ${allKeys.size}`);
|
||||||
|
console.log(`📊 使用中的 key: ${usedKeys.size}`);
|
||||||
|
|
||||||
|
// 未使用的 key
|
||||||
|
const unused = [...allKeys].filter(key => !usedKeys.has(key));
|
||||||
|
console.log(`\n❌ 未使用的 key (${unused.length}):\n`);
|
||||||
|
unused.sort().forEach(key => console.log(` - ${key}`));
|
||||||
|
|
||||||
|
// 缺失的 key
|
||||||
|
const missing = [...usedKeys].filter(key => {
|
||||||
|
if (!looksLikeI18nKey(key)) return false;
|
||||||
|
return !keyExists(key, allKeys);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (missing.length) {
|
||||||
|
console.log(`\n⚠️ 缺失的 key (${missing.length}):\n`);
|
||||||
|
missing.sort().forEach(key => console.log(` - ${key}`));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 硬编码文本
|
||||||
|
console.log('\n🔍 检测硬编码文本...');
|
||||||
|
const hardcoded = findHardcodedTexts();
|
||||||
|
|
||||||
|
if (hardcoded.length) {
|
||||||
|
console.log(`\n📝 硬编码文本 (${hardcoded.length}):\n`);
|
||||||
|
|
||||||
|
// 按文件分组
|
||||||
|
const byFile = new Map<string, HardcodedText[]>();
|
||||||
|
hardcoded.forEach(item => {
|
||||||
|
const list = byFile.get(item.file) || [];
|
||||||
|
list.push(item);
|
||||||
|
byFile.set(item.file, list);
|
||||||
|
});
|
||||||
|
|
||||||
|
byFile.forEach((items, file) => {
|
||||||
|
console.log(`\n 📄 ${file}`);
|
||||||
|
items.forEach(item => {
|
||||||
|
console.log(` L${item.line}: "${item.text}"`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// // 输出报告
|
||||||
|
// const report = {
|
||||||
|
// summary: {
|
||||||
|
// totalKeys: allKeys.size,
|
||||||
|
// usedKeys: usedKeys.size,
|
||||||
|
// unusedCount: unused.length,
|
||||||
|
// missingCount: missing.length,
|
||||||
|
// hardcodedCount: hardcoded.length,
|
||||||
|
// },
|
||||||
|
// unused,
|
||||||
|
// missing,
|
||||||
|
// hardcoded: hardcoded.map(h => ({
|
||||||
|
// file: h.file,
|
||||||
|
// line: h.line,
|
||||||
|
// text: h.text,
|
||||||
|
// })),
|
||||||
|
// };
|
||||||
|
|
||||||
|
// fs.writeFileSync('./i18n-report.json', JSON.stringify(report, null, 2));
|
||||||
|
// console.log('\n✅ 报告已保存到 i18n-report.json');
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
72
web-core/scripts/license.ts
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import * as fs from "fs";
|
||||||
|
import * as path from "path";
|
||||||
|
import checker from "license-checker";
|
||||||
|
|
||||||
|
const excludeNames = ["toonflow-serve"];
|
||||||
|
// const strictWhiteList = ["MIT", "BSD-2-Clause", "BSD-3-Clause", "BSD", "0BSD"];
|
||||||
|
const strictWhiteList: string[] = [];
|
||||||
|
|
||||||
|
// 检查是否在白名单协议
|
||||||
|
function isStrictWhiteLicense(license: string): boolean {
|
||||||
|
const normalized = license.replace(/[\(\)]/g, "").trim();
|
||||||
|
const parts = normalized.split(/\s*(OR|AND|\/)\s*/i).map((part) => part.trim());
|
||||||
|
return parts.every((part) => strictWhiteList.some((wl) => part === wl || part.replace(/ with .*/i, "") === wl));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取 package.json 里的直接依赖
|
||||||
|
function getDirectDependencyNames(): string[] {
|
||||||
|
const pkg = JSON.parse(fs.readFileSync(path.join(process.cwd(), "package.json"), "utf-8"));
|
||||||
|
const deps = Object.keys(pkg.dependencies ?? {});
|
||||||
|
const devDeps = Object.keys(pkg.devDependencies ?? {});
|
||||||
|
return [...deps, ...devDeps];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行主逻辑
|
||||||
|
checker.init({ start: process.cwd() }, (err: Error, packages: Record<string, any>) => {
|
||||||
|
if (err) {
|
||||||
|
console.error("license-checker 出错: ", err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
const directNames = getDirectDependencyNames();
|
||||||
|
|
||||||
|
interface PackageInfo {
|
||||||
|
name: string;
|
||||||
|
version: string;
|
||||||
|
licenses: string | string[];
|
||||||
|
repository: string | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const needDeclare: PackageInfo[] = [];
|
||||||
|
for (const fullName in packages) {
|
||||||
|
// fullName 一般形如 [@scope/]pkg@version, 但 license-checker 会带路径,如 @scope/name@1.0.0@./node_modules/@scope/name
|
||||||
|
// 所以可以正则只保留 name@version 部分
|
||||||
|
// nameMatch[1] 为包名,nameMatch[2] 为版本
|
||||||
|
const nameMatch = fullName.match(/^((?:@[^\/]+\/)?[^@]+)@([^@]+)$/);
|
||||||
|
if (!nameMatch) continue;
|
||||||
|
const name = nameMatch[1];
|
||||||
|
// 仅关注直接依赖
|
||||||
|
if (!directNames.includes(name!)) continue;
|
||||||
|
|
||||||
|
const info = packages[fullName];
|
||||||
|
const licenseArr: string[] = Array.isArray(info.licenses) ? info.licenses : [info.licenses];
|
||||||
|
if (!licenseArr.every(isStrictWhiteLicense)) {
|
||||||
|
needDeclare.push({
|
||||||
|
name: name!,
|
||||||
|
version: info.version,
|
||||||
|
licenses: licenseArr,
|
||||||
|
repository: info.repository,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 排除名单过滤
|
||||||
|
const filteredDeclare = needDeclare.filter((pkg) => pkg.name && !excludeNames.some((exName) => pkg.name.startsWith(exName)));
|
||||||
|
const content = filteredDeclare
|
||||||
|
.map(
|
||||||
|
(pkg) =>
|
||||||
|
`Name: ${pkg.name}\nLicense: ${Array.isArray(pkg.licenses) ? pkg.licenses.join(", ") : pkg.licenses}\nRepository: ${pkg.repository ?? "N/A"}`,
|
||||||
|
)
|
||||||
|
.join("\n\n-----------------------------\n\n");
|
||||||
|
fs.writeFileSync(path.resolve(process.cwd(), "NOTICES.txt"), content, "utf-8");
|
||||||
|
console.log("已生成依赖声明 NOTICES.txt");
|
||||||
|
});
|
||||||
132
web-core/src/App.vue
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
<template>
|
||||||
|
<titleBar v-if="isElectron" />
|
||||||
|
<t-config-provider :global-config="globalConfig">
|
||||||
|
<router-view></router-view>
|
||||||
|
</t-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import settingStore from "@/stores/setting";
|
||||||
|
import { merge } from "lodash-es";
|
||||||
|
import zhConfig from "tdesign-vue-next/es/locale/zh_CN";
|
||||||
|
import enConfig from "tdesign-vue-next/es/locale/en_US";
|
||||||
|
import { cachedLocale } from "@/locales";
|
||||||
|
import { initTheme } from "@/utils/theme";
|
||||||
|
import { normalizeApiBaseUrl } from "@/utils/apiBaseUrl";
|
||||||
|
import { type GlobalConfigProvider } from "tdesign-vue-next";
|
||||||
|
const { baseUrl, isElectron } = storeToRefs(settingStore());
|
||||||
|
import { config } from "md-editor-v3";
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => isElectron.value,
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
document.body.classList.add("is-electron");
|
||||||
|
} else {
|
||||||
|
document.body.classList.remove("is-electron");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
onBeforeMount(() => {
|
||||||
|
document.addEventListener("keydown", function (event) {
|
||||||
|
if (event.key === "F8") {
|
||||||
|
event.preventDefault();
|
||||||
|
debugger;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化主题
|
||||||
|
onMounted(() => {
|
||||||
|
getPort();
|
||||||
|
});
|
||||||
|
|
||||||
|
async function handleLinkClick(event: MouseEvent) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
const target = event.currentTarget as HTMLAnchorElement | null;
|
||||||
|
const url = target?.getAttribute("data-link") || target?.getAttribute("href");
|
||||||
|
if (!url) return false;
|
||||||
|
|
||||||
|
if (isElectron.value) {
|
||||||
|
await fetch(`toonflow://openurlwithbrowser?url=${encodeURIComponent(url)}`);
|
||||||
|
} else {
|
||||||
|
window.open(url, "_blank", "noopener,noreferrer");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
(window as any).handleLinkClick = handleLinkClick;
|
||||||
|
});
|
||||||
|
|
||||||
|
async function getPort() {
|
||||||
|
await nextTick();
|
||||||
|
await nextTick();
|
||||||
|
await nextTick();
|
||||||
|
await nextTick();
|
||||||
|
baseUrl.value = normalizeApiBaseUrl(baseUrl.value);
|
||||||
|
const canUseToonflowProtocol = navigator.userAgent.toLowerCase().includes("electron") || Boolean((window as any).electronAPI);
|
||||||
|
if (canUseToonflowProtocol) {
|
||||||
|
try {
|
||||||
|
const res = await fetch("toonflow://getAppUrl");
|
||||||
|
const data = await res.json();
|
||||||
|
if (data?.url) {
|
||||||
|
baseUrl.value = data.url;
|
||||||
|
isElectron.value = true;
|
||||||
|
}
|
||||||
|
} catch (error) {}
|
||||||
|
} else {
|
||||||
|
isElectron.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
config({
|
||||||
|
markdownItConfig(md) {
|
||||||
|
// 自定义链接渲染
|
||||||
|
const defaultRender =
|
||||||
|
md.renderer.rules.link_open ||
|
||||||
|
function (tokens, idx, options, env, self) {
|
||||||
|
return self.renderToken(tokens, idx, options);
|
||||||
|
};
|
||||||
|
md.renderer.rules.link_open = function (tokens, idx, options, env, self) {
|
||||||
|
const token = tokens[idx];
|
||||||
|
const href = token.attrGet("href");
|
||||||
|
|
||||||
|
if (href) {
|
||||||
|
// 添加 target="_blank" 在新窗口打开
|
||||||
|
token.attrSet("target", "_blank");
|
||||||
|
token.attrSet("rel", "noopener noreferrer");
|
||||||
|
|
||||||
|
// 或者添加自定义点击事件的标识
|
||||||
|
token.attrSet("data-link", href);
|
||||||
|
token.attrSet("onclick", "return handleLinkClick(event)");
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultRender(tokens, idx, options, env, self);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const tdesignLocaleMap: Record<string, object> = {
|
||||||
|
"zh-CN": zhConfig,
|
||||||
|
en: enConfig,
|
||||||
|
};
|
||||||
|
|
||||||
|
const customConfig: GlobalConfigProvider = {
|
||||||
|
calendar: {},
|
||||||
|
table: {},
|
||||||
|
pagination: {},
|
||||||
|
};
|
||||||
|
const globalConfig = computed<GlobalConfigProvider>(() => merge({}, tdesignLocaleMap[cachedLocale.value] || zhConfig, customConfig));
|
||||||
|
|
||||||
|
onBeforeMount(() => {
|
||||||
|
initTheme();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss"></style>
|
||||||
4
web-core/src/assets/atomgit.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="96" height="96">
|
||||||
|
<path d="M0 0 C2.60491411 3.39771405 2.43893626 6.83010556 2 11 C0.20437595 13.75329021 -1.05254922 15.52627461 -4 17 C-9.16062661 17.49941548 -9.16062661 17.49941548 -12 17 C-14.90799783 14.4555019 -15.90702057 13.04601863 -16.25 9.1875 C-16.1675 8.465625 -16.085 7.74375 -16 7 C-17.0725 7.639375 -18.145 8.27875 -19.25 8.9375 C-27.64061736 13.11803647 -42.1161507 13.9612831 -51 11 C-51.09796875 11.67804687 -51.1959375 12.35609375 -51.296875 13.0546875 C-52.09650113 18.03167082 -53.07549372 22.54151804 -55.0625 27.1875 C-58.18113878 34.59280707 -58.84191514 41.34103871 -56 49 C-51.69477815 55.71108112 -45.90514151 58.44542058 -38.375 60.3125 C-28.59646317 61.98237321 -17.61397475 61.2378015 -9 56 C-6.49898905 53.93089054 -4.42615578 51.9334749 -3 49 C-2.8015185 45.84858524 -2.8015185 45.84858524 -3 43 C-3.63502441 42.9498877 -4.27004883 42.89977539 -4.92431641 42.84814453 C-7.82522523 42.61482321 -10.72505632 42.37001416 -13.625 42.125 C-14.62402344 42.04636719 -15.62304688 41.96773437 -16.65234375 41.88671875 C-29.19293478 40.80706522 -29.19293478 40.80706522 -33 37 C-32.79953373 33.85936171 -32.54877905 31.72339057 -30.625 29.1875 C-24.50435236 24.71471903 -13.19717736 26.55890184 -6 27 C-2.41396623 27.60321914 0.69870236 28.49303823 4 30 C4.94875 30.4125 5.8975 30.825 6.875 31.25 C11.08743551 34.71906454 12.65632177 38.68972676 14 43.8125 C14.64326159 52.37282738 9.41850308 59.51339193 4.13671875 65.7421875 C-2.45750281 72.7101218 -11.41635656 78.38746195 -21.19140625 79.17700195 C-37.70773611 79.60385521 -50.14814106 78.46993862 -63 67 C-73.50321308 56.03782298 -76.52428161 45.45597262 -76.2734375 30.625 C-75.77333104 18.46399527 -69.95822491 8.40894719 -61.1875 0.1875 C-43.74979764 -14.14115465 -17.3489938 -15.03579462 0 0 Z " fill="#DA203E" transform="translate(80,13)"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.9 KiB |
BIN
web-core/src/assets/bg.png
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
web-core/src/assets/logo.png
Normal file
|
After Width: | Height: | Size: 43 KiB |
31
web-core/src/assets/logo.svg
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-label="ToonFlow logo">
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="tf-stem" x1="24" y1="24" x2="96" y2="98" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#64e1d3"/>
|
||||||
|
<stop offset="0.58" stop-color="#8ea3ff"/>
|
||||||
|
<stop offset="1" stop-color="#ffb46b"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="tf-play" x1="63" y1="42" x2="92" y2="82" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#ffffff"/>
|
||||||
|
<stop offset="1" stop-color="#dffdf7"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<path
|
||||||
|
fill="url(#tf-stem)"
|
||||||
|
d="M28 24h72c5.52 0 10 4.48 10 10v4c0 5.52-4.48 10-10 10H74v49c0 5.52-4.48 10-10 10H52c-5.52 0-10-4.48-10-10V48H28c-5.52 0-10-4.48-10-10v-4c0-5.52 4.48-10 10-10Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="url(#tf-stem)"
|
||||||
|
opacity=".9"
|
||||||
|
d="M42 74h56c6.63 0 12 5.37 12 12v2c0 6.63-5.37 12-12 12H42V74Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="#142133"
|
||||||
|
fill-opacity=".25"
|
||||||
|
d="M31 32h10a4 4 0 0 1 0 8H31a4 4 0 0 1 0-8Zm44 50h14a4 4 0 0 1 0 8H75a4 4 0 0 1 0-8Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="url(#tf-play)"
|
||||||
|
d="M68.4 47.58c-3.32-2.09-7.65.3-7.65 4.22v32.4c0 3.92 4.33 6.31 7.65 4.22l25.7-16.2c3.1-1.95 3.1-6.49 0-8.44l-25.7-16.2Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
1361
web-core/src/assets/main.scss
Normal file
BIN
web-core/src/assets/providers/ace.webp
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
web-core/src/assets/providers/adobe.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
web-core/src/assets/providers/adobefirefly.webp
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
web-core/src/assets/providers/agentvoice.webp
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
web-core/src/assets/providers/agui.webp
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
web-core/src/assets/providers/ai2.webp
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
web-core/src/assets/providers/ai21.webp
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
web-core/src/assets/providers/ai302.webp
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
web-core/src/assets/providers/ai360.webp
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
web-core/src/assets/providers/aihubmix.webp
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
web-core/src/assets/providers/aimass.webp
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
web-core/src/assets/providers/aionlabs.webp
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
web-core/src/assets/providers/aistudio.webp
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
web-core/src/assets/providers/akashchat.webp
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
web-core/src/assets/providers/alephalpha.webp
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
web-core/src/assets/providers/alibaba.webp
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
web-core/src/assets/providers/alibabacloud.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
web-core/src/assets/providers/amp.webp
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
web-core/src/assets/providers/antgroup.webp
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
web-core/src/assets/providers/anthropic.webp
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
web-core/src/assets/providers/antigravity.webp
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
web-core/src/assets/providers/anyscale.webp
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
web-core/src/assets/providers/apertis.webp
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
web-core/src/assets/providers/apple.webp
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
web-core/src/assets/providers/arcee.webp
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
web-core/src/assets/providers/askverdict.webp
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
web-core/src/assets/providers/assemblyai.webp
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
web-core/src/assets/providers/atlascloud.webp
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
web-core/src/assets/providers/automatic.webp
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
web-core/src/assets/providers/aws.webp
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
web-core/src/assets/providers/aya.webp
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
web-core/src/assets/providers/azure.webp
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
web-core/src/assets/providers/azureai.webp
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
web-core/src/assets/providers/baai.webp
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
web-core/src/assets/providers/baichuan.webp
Normal file
|
After Width: | Height: | Size: 8.0 KiB |
BIN
web-core/src/assets/providers/baidu.webp
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
web-core/src/assets/providers/baiducloud.webp
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
web-core/src/assets/providers/bailian.webp
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
web-core/src/assets/providers/baseten.webp
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
web-core/src/assets/providers/bedrock.webp
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
web-core/src/assets/providers/bfl.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
web-core/src/assets/providers/bilibili.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
web-core/src/assets/providers/bilibiliindex.webp
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
web-core/src/assets/providers/bing.webp
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
web-core/src/assets/providers/briaai.webp
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
web-core/src/assets/providers/burncloud.webp
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
web-core/src/assets/providers/bytedance.webp
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
web-core/src/assets/providers/capcut.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
web-core/src/assets/providers/centml.webp
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
web-core/src/assets/providers/cerebras.webp
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
web-core/src/assets/providers/chatglm.webp
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
web-core/src/assets/providers/cherrystudio.webp
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
web-core/src/assets/providers/civitai.webp
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
web-core/src/assets/providers/claude.webp
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
web-core/src/assets/providers/claudecode.webp
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
web-core/src/assets/providers/cline.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
web-core/src/assets/providers/clipdrop.webp
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
web-core/src/assets/providers/cloudflare.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
web-core/src/assets/providers/codeflicker.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
web-core/src/assets/providers/codegeex.webp
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
web-core/src/assets/providers/codex.webp
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
web-core/src/assets/providers/cogvideo.webp
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
web-core/src/assets/providers/cogview.webp
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
web-core/src/assets/providers/cohere.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
web-core/src/assets/providers/colab.webp
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
web-core/src/assets/providers/cometapi.webp
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
web-core/src/assets/providers/comfyui.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
web-core/src/assets/providers/commanda.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
web-core/src/assets/providers/copilot.webp
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
web-core/src/assets/providers/copilotkit.webp
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
web-core/src/assets/providers/coqui.webp
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
web-core/src/assets/providers/coze.webp
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
web-core/src/assets/providers/crewai.webp
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
web-core/src/assets/providers/crusoe.webp
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
web-core/src/assets/providers/cursor.webp
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
web-core/src/assets/providers/cybercut.webp
Normal file
|
After Width: | Height: | Size: 13 KiB |