diff --git a/.env b/.env index eb9c96265..f471f1720 100644 --- a/.env +++ b/.env @@ -8,7 +8,7 @@ VITE_GLOB_OPEN_LONG_REPLY=true # git commit hash # GITHUB_SHA -VITE_GIT_COMMIT_HASH=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +VITE_GIT_COMMIT_HASH= # release version -VITE_RELEASE_VERSION=v0.0.0 +VITE_RELEASE_VERSION=v0.0.1 diff --git a/.github/workflows/build_docker.yml b/.github/workflows/build_docker.yml index 650baf1d7..def9398f7 100644 --- a/.github/workflows/build_docker.yml +++ b/.github/workflows/build_docker.yml @@ -1,127 +1,152 @@ +# 工作流名称 name: Build and push docker image +# 触发条件配置 on: push: - branches: [main] + branches: [main] # 当推送到main分支时触发 release: - types: [created] # This will only run on new releases + types: [created] # 当创建新的release时触发 +# 定义作业 jobs: + # 第一个作业:更新Docker Hub描述 docker_hub_description: - name: Docker Hub description - runs-on: ubuntu-latest + name: Docker Hub description # 作业名称 + runs-on: ubuntu-latest # 运行环境 steps: + # 检出代码 - name: Checkout uses: actions/checkout@v4 with: - sparse-checkout: | - README.en.md + sparse-checkout: | # 只检出特定文件 + README.en.md # 仅检出英文README文件 + + # 更新Docker Hub仓库描述 - name: Docker Hub Description uses: peter-evans/dockerhub-description@v4 with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - repository: ${{ vars.DOCKERHUB_NAMESPACE }}/chatgpt-web - # Description length should be no longer than 100 characters. + username: ${{ secrets.DOCKERHUB_USERNAME }} # Docker Hub用户名 + password: ${{ secrets.DOCKERHUB_TOKEN }} # Docker Hub访问令牌 + repository: jsntwdj/zjai-web # 目标仓库 + # 简短描述(不超过100字符) short-description: A third-party ChatGPT Web UI page, through the official OpenAI completion API. - readme-filepath: README.en.md - enable-url-completion: true + readme-filepath: README.en.md # 使用的README文件路径 + enable-url-completion: true # 启用URL自动补全 + # 第二个作业:构建多平台镜像 build: - name: Build multi-platform images + name: Build multi-platform images # 作业名称 strategy: - fail-fast: false + fail-fast: false # 一个平台失败不影响其他平台 matrix: include: - - platform: linux/amd64 - os: ubuntu-latest - - platform: linux/arm64 - os: ubuntu-24.04-arm - runs-on: ${{ matrix.os }} + - platform: linux/amd64 # AMD64架构 + os: ubuntu-latest # 使用的运行器 + - platform: linux/arm64 # ARM64架构 + os: ubuntu-24.04-arm # ARM架构专用运行器 + runs-on: ${{ matrix.os }} # 使用矩阵中定义的操作系统 steps: + # 检出代码 - name: Checkout uses: actions/checkout@v4 + # 准备环境变量 - name: Prepare run: | platform=${{ matrix.platform }} - echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV # 将平台信息转换为环境变量格式 + # 生成Docker元数据(标签等) - name: Docker meta - id: meta + id: meta # 步骤ID,用于后续引用 uses: docker/metadata-action@v5 with: - images: ${{ vars.DOCKERHUB_NAMESPACE }}/chatgpt-web + images: jsntwdj/zjai-web # 目标镜像名称 + # 登录Docker Hub - name: Login to Docker Hub uses: docker/login-action@v3 with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} # Docker Hub用户名 + password: ${{ secrets.DOCKERHUB_TOKEN }} # Docker Hub访问令牌 + # 设置Docker Buildx(多平台构建工具) - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + # 构建并推送镜像 - name: Build and push by digest - id: build + id: build # 步骤ID,用于后续引用 uses: docker/build-push-action@v6 with: - context: . - platforms: ${{ matrix.platform }} - labels: ${{ steps.meta.outputs.labels }} - build-args: | - GIT_COMMIT_HASH=${{ github.sha }} - RELEASE_VERSION=${{ github.ref_name }} - outputs: type=image,name=${{ vars.DOCKERHUB_NAMESPACE }}/chatgpt-web,push-by-digest=true,name-canonical=true,push=true - + context: . # 构建上下文为当前目录 + platforms: ${{ matrix.platform }} # 使用矩阵中定义的平台 + labels: ${{ steps.meta.outputs.labels }} # 使用元数据步骤生成的标签 + build-args: | # 构建参数 + GIT_COMMIT_HASH=${{ github.sha }} # 注入Git提交哈希 + RELEASE_VERSION=${{ github.ref_name }} # 注入发布版本号 + outputs: type=image,name=jsntwdj/zjai-web,push-by-digest=true,name-canonical=true,push=true + + # 导出镜像摘要(digest) - name: Export digest run: | - mkdir -p ${{ runner.temp }}/digests - digest="${{ steps.build.outputs.digest }}" - touch "${{ runner.temp }}/digests/${digest#sha256:}" + mkdir -p ${{ runner.temp }}/digests # 创建临时目录 + digest="${{ steps.build.outputs.digest }}" # 获取构建步骤输出的摘要 + touch "${{ runner.temp }}/digests/${digest#sha256:}" # 保存摘要到文件 + # 上传摘要文件作为制品 - name: Upload digest uses: actions/upload-artifact@v4 with: - name: digests-${{ env.PLATFORM_PAIR }} - path: ${{ runner.temp }}/digests/* - if-no-files-found: error - retention-days: 1 + name: digests-${{ env.PLATFORM_PAIR }} # 制品名称包含平台信息 + path: ${{ runner.temp }}/digests/* # 上传所有摘要文件 + if-no-files-found: error # 如果没有文件则报错 + retention-days: 1 # 制品保留1天 + # 第三个作业:合并多平台镜像 merge: - name: Merge multi-platform images - runs-on: ubuntu-latest + name: Merge multi-platform images # 作业名称 + runs-on: ubuntu-latest # 运行环境 needs: - - build + - build # 依赖build作业完成 steps: + # 下载之前上传的摘要制品 - name: Download digests uses: actions/download-artifact@v4 with: - path: ${{ runner.temp }}/digests - pattern: digests-* - merge-multiple: true + path: ${{ runner.temp }}/digests # 下载路径 + pattern: digests-* # 匹配所有摘要制品 + merge-multiple: true # 合并多个制品 + # 登录Docker Hub - name: Login to Docker Hub uses: docker/login-action@v3 with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} # Docker Hub用户名 + password: ${{ secrets.DOCKERHUB_TOKEN }} # Docker Hub访问令牌 + # 设置Docker Buildx - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + # 生成Docker元数据 - name: Docker meta - id: meta + id: meta # 步骤ID,用于后续引用 uses: docker/metadata-action@v5 with: - images: ${{ vars.DOCKERHUB_NAMESPACE }}/chatgpt-web + images: jsntwdj/zjai-web # 目标镜像名称 + # 创建多平台清单并推送 - name: Create manifest list and push - working-directory: ${{ runner.temp }}/digests + working-directory: ${{ runner.temp }}/digests # 工作目录设置为摘要文件所在目录 run: | + # 使用jq解析元数据生成标签,并创建多平台清单 docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - $(printf '${{ vars.DOCKERHUB_NAMESPACE }}/chatgpt-web@sha256:%s ' *) + $(printf 'jsntwdj/zjai-web@sha256:%s ' *) + # 检查生成的镜像 - name: Inspect image run: | - docker buildx imagetools inspect ${{ vars.DOCKERHUB_NAMESPACE }}/chatgpt-web:${{ steps.meta.outputs.version }} + # 检查镜像详情,验证多平台支持 + docker buildx imagetools inspect jsntwdj/zjai-web:${{ steps.meta.outputs.version }} diff --git a/Dockerfile b/Dockerfile index 9ccc30228..8121c13df 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ # build front-end FROM node:22-alpine AS frontend -ARG GIT_COMMIT_HASH=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -ARG RELEASE_VERSION=v0.0.0 +ARG GIT_COMMIT_HASH=0 +ARG RELEASE_VERSION=v1.0.0 ENV VITE_GIT_COMMIT_HASH=$GIT_COMMIT_HASH ENV VITE_RELEASE_VERSION=$RELEASE_VERSION diff --git a/index.html b/index.html index 8096a3b3c..6099965de 100644 --- a/index.html +++ b/index.html @@ -82,3 +82,5 @@ + + diff --git a/prompts-zj.json b/prompts-zj.json new file mode 100644 index 000000000..f32a94c72 --- /dev/null +++ b/prompts-zj.json @@ -0,0 +1,34 @@ +[ + { + "act": "担任造价工程师", + "prompt": "我希望你假定自己是造价工程师,根据提问,回答造价专业的问题" + }, + { + "act": "担任面试官", + "prompt": "我想让你担任造价工程师面试官。我将成为候选人,您将向我询问造价工程师职位的面试问题。我希望你只作为面试官回答。不要一次写出所有的问题。我希望你只对我进行采访。问我问题,等待我的回答。不要写解释。像面试官一样一个一个问我,等我回答。我的第一句话是“面试官你好”\n" + }, + { + "act": "充当 Excel 工作表", + "prompt": "我希望你充当基于文本的 excel。您只会回复我基于文本的 10 行 Excel 工作表,其中行号和单元格字母作为列(A 到 L)。第一列标题应为空以引用行号。我会告诉你在单元格中写入什么,你只会以文本形式回复 excel 表格的结果,而不是其他任何内容。不要写解释。我会写你的公式,你会执行公式,你只会回复 excel 表的结果作为文本。首先,回复我空表。\n" + }, + { + "act": "担任造价写作导师", + "prompt": "我想让你做一个造价写作导师。我将为您提供一名需要帮助改进其写作的学生,您的任务是使用人工智能工具(例如自然语言处理)向学生提供有关如何改进其作文的反馈。您还应该利用您在有效写作技巧方面的修辞知识和经验来建议学生可以更好地以书面形式表达他们的想法和想法的方法。我的第一个请求是“我需要有人帮我修改我的硕士论文”。\n" + }, + { + "act": "作为造价师的招聘人员", + "prompt": "我想让你担任招聘人员。我将提供一些关于职位空缺的信息,而你的工作是制定寻找合格申请人的策略。这可能包括通过社交媒体、社交活动甚至参加招聘会接触潜在候选人,以便为每个职位找到最合适的人选。我的第一个请求是“我需要帮助改进我的简历。”\n" + }, + { + "act": "担任职业顾问", + "prompt": "我想让你担任职业顾问。我将为您提供一个在职业生涯中寻求指导的人,您的任务是帮助他们根据自己的技能、兴趣和经验确定最适合的职业。您还应该对可用的各种选项进行研究,解释不同行业的就业市场趋势,并就哪些资格对追求特定领域有益提出建议。我的第一个请求是“我想建议那些想在软件工程领域从事潜在职业的人。”\n" + }, + { + "act": "担任造价顾问", + "prompt": "我希望你担任造价顾问,为各种造价方案提供建议,例如如何套定额、如何计价、如何计算工程量等" + }, + { + "act":"论文优化助理", + "prompt":"你现在来扮演一个大学生毕业论文指导老师,研究方向是《自行输入》,现在你来开始教我怎么做。比如先给我列出此研究方向的大纲。" + } +] diff --git a/public/favicon.ico b/public/favicon.ico index fd7ff8c4e..9658b9d0f 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/favicon.svg b/public/favicon.svg index ab38bce92..c50272b9b 100644 --- a/public/favicon.svg +++ b/public/favicon.svg @@ -1 +1,68 @@ - \ No newline at end of file + + + + diff --git a/public/pwa-192x192.png b/public/pwa-192x192.png index 05826b3c6..3ef07dcdd 100644 Binary files a/public/pwa-192x192.png and b/public/pwa-192x192.png differ diff --git a/public/pwa-512x512.png b/public/pwa-512x512.png index 84adb825a..4032f5b36 100644 Binary files a/public/pwa-512x512.png and b/public/pwa-512x512.png differ diff --git a/service/src/storage/config.ts b/service/src/storage/config.ts index 2910d9230..9af91cf25 100644 --- a/service/src/storage/config.ts +++ b/service/src/storage/config.ts @@ -79,7 +79,9 @@ export async function getOriginConfig() { if (!config.advancedConfig) { config.advancedConfig = new AdvancedConfig( - 'You are a large language model. Follow the user\'s instructions carefully. Respond using markdown (latex start with $).', + + '你是江苏省的一名造价工程师,一个造价专业的AI大模型。请仔细遵循用户的指示。使用 Markdown 进行回复(LaTeX 以 $ 开始)。', + 0.8, 1, ) @@ -92,11 +94,10 @@ export async function getOriginConfig() { ) } - if (!config.searchConfig) { - config.searchConfig = new SearchConfig() - config.searchConfig.enabled = false - config.searchConfig.options = { apiKey: '', maxResults: 10, includeRawContent: false } - } + + if (!isNotEmptyString(config.siteConfig.chatModels)) + config.siteConfig.chatModels = 'zjai' + if (!isNotEmptyString(config.siteConfig.chatModels)) config.siteConfig.chatModels = 'gpt-4.1,gpt-4.1-mini,gpt-4.1-nano' diff --git a/service/src/storage/mongo.ts b/service/src/storage/mongo.ts index 5ebff6596..42b624788 100644 --- a/service/src/storage/mongo.ts +++ b/service/src/storage/mongo.ts @@ -530,7 +530,9 @@ async function initUserInfo(userInfo: WithId) { if (userInfo.config == null) userInfo.config = new UserConfig() if (userInfo.config.chatModel == null) - userInfo.config.chatModel = '' + + userInfo.config.chatModel = 'zjai' + if (userInfo.roles == null || userInfo.roles.length <= 0) { userInfo.roles = [] if (process.env.ROOT_USER === userInfo.email.toLowerCase()) diff --git a/src/assets/avatar.jpg b/src/assets/avatar.jpg index 9be9587ff..8c1909468 100644 Binary files a/src/assets/avatar.jpg and b/src/assets/avatar.jpg differ diff --git a/src/assets/avatar.jpg.bak b/src/assets/avatar.jpg.bak new file mode 100644 index 000000000..9be9587ff Binary files /dev/null and b/src/assets/avatar.jpg.bak differ diff --git a/src/assets/recommend.json b/src/assets/recommend.json index 8f29eb700..926944897 100644 --- a/src/assets/recommend.json +++ b/src/assets/recommend.json @@ -1,14 +1,10 @@ [ { - "title": "awesome-chatgpt-prompts-zh", - "desc": "ChatGPT 中文调教指南", - "downloadUrl": "https://raw.githubusercontent.com/PlexPt/awesome-chatgpt-prompts-zh/main/prompts-zh.json", - "url": "https://github.com/PlexPt/awesome-chatgpt-prompts-zh" - }, - { - "title": "awesome-chatgpt-prompts-zh-TW", - "desc": "ChatGPT 中文調教指南 (透過 OpenAI / OpenCC 協助,從簡體中文轉換為繁體中文的版本)", - "downloadUrl": "https://raw.githubusercontent.com/PlexPt/awesome-chatgpt-prompts-zh/main/prompts-zh-TW.json", - "url": "https://github.com/PlexPt/awesome-chatgpt-prompts-zh" + "title": "zje", + "key": "造价e星球", + "desc": "造价Ai 造价师专用调教指南", + "downloadUrl": "https://raw.githubusercontent.com/wudingjian/zjai-web/main/prompts-zj.json", + "url": "https://www.zje.cc" + } ] diff --git a/src/assets/zje.jpg b/src/assets/zje.jpg new file mode 100644 index 000000000..2ddd60161 Binary files /dev/null and b/src/assets/zje.jpg differ diff --git a/src/components/common/GitHubSite/index.vue b/src/components/common/GitHubSite/index.vue index 607cf90c0..37de314af 100644 --- a/src/components/common/GitHubSite/index.vue +++ b/src/components/common/GitHubSite/index.vue @@ -1,18 +1,12 @@ + diff --git a/src/store/modules/auth/index.ts b/src/store/modules/auth/index.ts index d1ca8716e..d906c9607 100644 --- a/src/store/modules/auth/index.ts +++ b/src/store/modules/auth/index.ts @@ -54,8 +54,11 @@ export const useAuthStore = defineStore('auth-store', { this.token = token const decoded = jwtDecode(token) as UserInfo const userStore = useUserStore() - if (decoded.config === undefined || decoded.config === null) + if (decoded.config === undefined || decoded.config === null){ decoded.config = new UserConfig() + decoded.config.chatModel = 'zjai' + } + await userStore.updateUserInfo(false, { avatar: decoded.avatar, diff --git a/src/store/modules/user/helper.ts b/src/store/modules/user/helper.ts index c4fc9818c..8b173de7b 100644 --- a/src/store/modules/user/helper.ts +++ b/src/store/modules/user/helper.ts @@ -34,10 +34,12 @@ export function defaultSetting(): UserState { name: '', description: '', root: false, - config: { chatModel: '' }, + + config: { chatModel: 'zjai' }, roles: [], advanced: { - systemMessage: 'You are a large language model. Follow the user\'s instructions carefully. Respond using markdown (latex start with $).', + systemMessage: '你是江苏省的一名造价工程师,一个造价专业的AI大模型。请仔细遵循用户的指示。使用 Markdown 进行回复(LaTeX 以 $ 开始)。', + temperature: 0.8, top_p: 1, }, @@ -51,11 +53,13 @@ export function getLocalState(): UserState { if (localSetting != null && localSetting.userInfo != null) { if (localSetting.userInfo.config == null) { localSetting.userInfo.config = new UserConfig() - localSetting.userInfo.config.chatModel = '' + + localSetting.userInfo.config.chatModel = 'zjai' } if (!localSetting.userInfo.advanced) { localSetting.userInfo.advanced = { - systemMessage: 'You are a large language model. Follow the user\'s instructions carefully. Respond using markdown (latex start with $).', + systemMessage: '你是江苏省的一名造价工程师,一个造价专业的AI大模型。请仔细遵循用户的指示。使用 Markdown 进行回复(LaTeX 以 $ 开始)。', + temperature: 0.8, top_p: 1, } diff --git a/src/views/chat/components/Message/Avatar.vue b/src/views/chat/components/Message/Avatar.vue index 90b52de3a..15965025a 100644 --- a/src/views/chat/components/Message/Avatar.vue +++ b/src/views/chat/components/Message/Avatar.vue @@ -21,7 +21,7 @@ const avatar = computed(() => userStore.userInfo.avatar)