chore: 修复登录页与前端开发服务器配置
- vite dev server 端口改为 5000 并启用 strictPort,端口冲突时拒绝启动 - AGENTS.md 更新前端目录结构说明(移除已删除的 ERB/enterprise 目录)及端口文档 - v3 登录页精简:移除 useBranding/globalConfig 依赖,去掉忘记密码链接 - 中文登录表单翻译优化(Email → 电子邮件)
This commit is contained in:
@@ -19,9 +19,6 @@ backend/ # Go backend (the Go module lives here)
|
||||
tests/ # e2e tests + test helpers
|
||||
frontend/ # Chatwoot Vue 3 frontend (vendored for customization)
|
||||
app/javascript/ # Vue SPA source (dashboard, widget, sdk, portal, superadmin)
|
||||
app/views/ # ERB templates (vite-plugin-ruby entrypoint resolution)
|
||||
config/vite.json # Vite-Rails bridge config
|
||||
enterprise/ # Enterprise edition frontend overlay
|
||||
package.json # pnpm + Vite + Vue 3 toolchain
|
||||
deploy/ # Deployment artifacts
|
||||
docker/ # Dockerfile, Dockerfile.dev, docker-compose.{yml,dev,prod,test}.yml
|
||||
@@ -145,7 +142,7 @@ Key decoupling changes:
|
||||
# From repo root — unified dev workflow
|
||||
pnpm install # install all workspace deps
|
||||
pnpm dev:backend # start Go backend (air hot-reload, port 3000)
|
||||
pnpm dev:frontend # start Vite dev server (port 3036, proxies API to :3000)
|
||||
pnpm dev:frontend # start Vite dev server (port 5000, proxies API to :3000)
|
||||
pnpm dev # start both concurrently
|
||||
|
||||
# Frontend-only (from frontend/)
|
||||
@@ -165,3 +162,15 @@ Default `CHATWOOT_DIR` points to `../frontend`.
|
||||
- Do not add Go files to `backend/scripts/legacy/` expecting them to be excluded — `go build ./...` compiles them; keep that directory for one-off scripts only.
|
||||
- Do not commit `.env`, `coverage.out`, `bin/`, or `tmp/`.
|
||||
- Do not rewrite git history or force-push without explicit instruction.
|
||||
|
||||
|
||||
<!-- CODEGRAPH_START -->
|
||||
## CodeGraph
|
||||
|
||||
In repositories indexed by CodeGraph (a `.codegraph/` directory exists at the repo root), reach for it BEFORE grep/find or reading files when you need to understand or locate code:
|
||||
|
||||
- **MCP tool** (when available): `codegraph_explore` answers most code questions in one call — the relevant symbols' verbatim source plus the call paths between them, including dynamic-dispatch hops grep can't follow. Name a file or symbol in the query to read its current line-numbered source. If it's listed but deferred, load it by name via tool search.
|
||||
- **Shell** (always works): `codegraph explore "<symbol names or question>"` prints the same output.
|
||||
|
||||
If there is no `.codegraph/` directory, skip CodeGraph entirely — indexing is the user's decision.
|
||||
<!-- CODEGRAPH_END -->
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
"LOGIN": {
|
||||
"TITLE": "登录到Chatwoot",
|
||||
"EMAIL": {
|
||||
"LABEL": "Email",
|
||||
"PLACEHOLDER": "实例 {'@'}companyname.com",
|
||||
"LABEL": "电子邮件",
|
||||
"PLACEHOLDER": "电子邮件",
|
||||
"ERROR": "请输入一个有效的电子邮件"
|
||||
},
|
||||
"PASSWORD": {
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
<script>
|
||||
// utils and composables
|
||||
import { login } from '../../api/auth';
|
||||
import { mapGetters } from 'vuex';
|
||||
import { useAlert } from 'dashboard/composables';
|
||||
import { required, email } from '@vuelidate/validators';
|
||||
import { useVuelidate } from '@vuelidate/core';
|
||||
import { SESSION_STORAGE_KEYS } from 'dashboard/constants/sessionStorage';
|
||||
import SessionStorage from 'shared/helpers/sessionStorage';
|
||||
import { useBranding } from 'shared/composables/useBranding';
|
||||
|
||||
// components
|
||||
import SimpleDivider from '../../components/Divider/SimpleDivider.vue';
|
||||
@@ -46,9 +44,7 @@ export default {
|
||||
authError: { type: String, default: '' },
|
||||
},
|
||||
setup() {
|
||||
const { replaceInstallationName } = useBranding();
|
||||
return {
|
||||
replaceInstallationName,
|
||||
v$: useVuelidate(),
|
||||
};
|
||||
},
|
||||
@@ -84,7 +80,6 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({ globalConfig: 'globalConfig/get' }),
|
||||
allowedLoginMethods() {
|
||||
return window.chatwootConfig.allowedLoginMethods || ['email'];
|
||||
},
|
||||
@@ -227,14 +222,8 @@ export default {
|
||||
|
||||
<template>
|
||||
<main
|
||||
class="flex flex-col w-full min-h-screen py-20 bg-n-brand/5 dark:bg-n-background sm:px-6 lg:px-8"
|
||||
class="flex flex-col items-center justify-center w-full min-h-screen bg-n-brand/5 dark:bg-n-background sm:px-6 lg:px-8"
|
||||
>
|
||||
<section class="max-w-5xl mx-auto">
|
||||
<h2 class="text-3xl font-medium text-center text-n-slate-12">
|
||||
{{ replaceInstallationName($t('LOGIN.TITLE')) }}
|
||||
</h2>
|
||||
</section>
|
||||
|
||||
<!-- MFA Verification Section -->
|
||||
<section v-if="mfaRequired" class="mt-11">
|
||||
<MfaVerification
|
||||
@@ -300,17 +289,7 @@ export default {
|
||||
:placeholder="$t('LOGIN.PASSWORD.PLACEHOLDER')"
|
||||
:has-error="v$.credentials.password.$error"
|
||||
@input="v$.credentials.password.$touch"
|
||||
>
|
||||
<p v-if="!globalConfig.disableUserProfileUpdate">
|
||||
<router-link
|
||||
to="auth/reset/password"
|
||||
class="text-sm text-link"
|
||||
tabindex="4"
|
||||
>
|
||||
{{ $t('LOGIN.FORGOT_PASSWORD') }}
|
||||
</router-link>
|
||||
</p>
|
||||
</FormInput>
|
||||
/>
|
||||
<NextButton
|
||||
lg
|
||||
type="submit"
|
||||
|
||||
@@ -83,7 +83,8 @@ export default defineConfig({
|
||||
// Dev server: SPA mode for dashboard + widget.html route
|
||||
server: {
|
||||
host: '0.0.0.0',
|
||||
port: 3036,
|
||||
port: 5000,
|
||||
strictPort: true, // port conflict → refuse to start instead of auto-incrementing
|
||||
// Serve widget.html for /widget path (widget iframe), index.html for SPA routes
|
||||
historyApiFallback: {
|
||||
rewrites: [
|
||||
|
||||
Reference in New Issue
Block a user