Compare commits
41 Commits
260db8e896
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 967996429b | |||
| f88129f8a9 | |||
| 02ccd546bc | |||
| 4006e7f1c1 | |||
| 352f2b7bae | |||
| 1839bae545 | |||
| 93cb27238b | |||
| a0de3ce96d | |||
| 989c8468f0 | |||
| f8a864d740 | |||
| afde6d2024 | |||
| fe4b39ac97 | |||
| c25e5042dd | |||
| 27849503b3 | |||
| 5fdf071510 | |||
| ff3e62506c | |||
| 24accf803d | |||
| b5dcc80759 | |||
| a294116696 | |||
| d45f0b0ecd | |||
| 2a522e06a0 | |||
| af3bff6d80 | |||
| d9d57066fc | |||
| e34986d09d | |||
| 57adf91646 | |||
| 016c1de922 | |||
| a167d3f2ba | |||
| fb7bf53680 | |||
| cb453297be | |||
| a2f4f946ac | |||
| 67d5bb6874 | |||
| db20117500 | |||
| f3e4408dc0 | |||
| c2d13187f0 | |||
| 7155dedc8d | |||
| de8a6b9dc7 | |||
| 9c562143da | |||
| 21fb901580 | |||
| 29eb464772 | |||
| 6f5d696c2d | |||
| 14a3e467f8 |
90
.gitea/workflows/develop_build_commit.yaml
Normal file
90
.gitea/workflows/develop_build_commit.yaml
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
name: git commit 控制 AiDA WEB-Node.js 开发分支构建部署
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- dev_vite
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: "contains(github.event.head_commit.message, '[run build]')"
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [ 18.18.0 ]
|
||||||
|
env:
|
||||||
|
REMOTE_DEPLOY_PATH: /workspace/workspace_aida/DevelopVersion/develop-aida-web-front
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 0.记录开始时间
|
||||||
|
id: build_start_time
|
||||||
|
run: echo "current_time=$(TZ='Asia/Hong_Kong' date '+%Y-%m-%d %H:%M:%S %Z')" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: 1.检出代码
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: dev_vite
|
||||||
|
|
||||||
|
- name: 2.设置 Node.js 环境
|
||||||
|
uses: actions/setup-node@v6
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
- run: npm install
|
||||||
|
- run: npm run build:dev
|
||||||
|
- run: ls -l
|
||||||
|
|
||||||
|
- name: 3.同步文件到远程服务器
|
||||||
|
uses: appleboy/scp-action@v0.1.7
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SERVER_HOST }}
|
||||||
|
username: ${{ secrets.SERVER_USER }}
|
||||||
|
key: ${{ secrets.SSH_KEY }}
|
||||||
|
source: "./dist/*"
|
||||||
|
target: ${{ env.REMOTE_DEPLOY_PATH }}
|
||||||
|
ssh_options: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
|
||||||
|
strip_components: 0
|
||||||
|
|
||||||
|
- name: 4. 远程重载 Nginx 配置
|
||||||
|
uses: appleboy/ssh-action@v1.0.3
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SERVER_HOST }}
|
||||||
|
username: ${{ secrets.SERVER_USER }}
|
||||||
|
key: ${{ secrets.SSH_KEY }}
|
||||||
|
# 核心:执行 Nginx 重载命令
|
||||||
|
script: |
|
||||||
|
echo "尝试重载 Nginx 服务..."
|
||||||
|
# 💡 注意:执行此命令需要服务器用户具有 sudo 权限,并且配置了 NOPASSWD。
|
||||||
|
# 否则工作流可能会因为权限不足而失败。
|
||||||
|
sudo systemctl reload nginx
|
||||||
|
echo "Nginx 重载命令已发送。"
|
||||||
|
|
||||||
|
- name: 5.发送构建结果邮件
|
||||||
|
if: always() # 无论上一步是否失败,都执行此步骤
|
||||||
|
uses: dawidd6/action-send-mail@v3
|
||||||
|
with:
|
||||||
|
|
||||||
|
from: ${{ secrets.MAIL_USERNAME }}
|
||||||
|
# --- 邮件配置 ---
|
||||||
|
server_address: smtp.gmail.com # 替换为你的SMTP服务器地址
|
||||||
|
server_port: 465 # 替换为你的SMTP端口 (通常是465或587)
|
||||||
|
username: ${{ secrets.MAIL_USERNAME }} # 存储在Secrets中的邮箱用户名
|
||||||
|
password: ${{ secrets.MAIL_PASSWORD }} # 存储在Secrets中的邮箱密码
|
||||||
|
subject: 'Gitea Actions 构建通知: ${{ job.status }} - AiDA back-java Develop'
|
||||||
|
# 收件人列表,可以根据需要更改
|
||||||
|
to: 'xupei3360@163.com,txli@aidlab.hk,cgzhou@aidlab.hk,zchengrong@yeah.net' # 替换为实际收件人邮箱
|
||||||
|
|
||||||
|
# --- 邮件正文内容 ---
|
||||||
|
body: |
|
||||||
|
项目: AiDA back-java Develop
|
||||||
|
分支: dev/3.1_release_merge
|
||||||
|
|
||||||
|
🎉 构建结果: ${{ job.status }}
|
||||||
|
|
||||||
|
📅 构建时间: ${{ steps.build_start_time.outputs.current_time }}
|
||||||
|
|
||||||
|
🔗 构建链接: ${{ gitea.server_url }}/${{ gitea.repository.owner.name }}/${{ gitea.repository.name }}/actions/runs/${{ gitea.run_id }}
|
||||||
|
|
||||||
|
# 确保邮件内容为纯文本,或者你可以设置为 html: true 并调整 body
|
||||||
|
content_type: text/plain
|
||||||
85
.gitea/workflows/develop_build_manual.yaml
Normal file
85
.gitea/workflows/develop_build_manual.yaml
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
name: 手动触发 AiDA WEB-Node.js 开发分支构建部署
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [ 18.18.0 ]
|
||||||
|
env:
|
||||||
|
REMOTE_DEPLOY_PATH: /workspace/workspace_aida/DevelopVersion/develop-aida-web-front
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 0.记录开始时间
|
||||||
|
id: build_start_time
|
||||||
|
run: echo "current_time=$(TZ='Asia/Hong_Kong' date '+%Y-%m-%d %H:%M:%S %Z')" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: 1.检出代码
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: dev_vite
|
||||||
|
|
||||||
|
- name: 2.设置 Node.js 环境
|
||||||
|
uses: actions/setup-node@v6
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
- run: npm install
|
||||||
|
- run: npm run build:dev
|
||||||
|
- run: ls -l
|
||||||
|
|
||||||
|
- name: 3.同步文件到远程服务器
|
||||||
|
uses: appleboy/scp-action@v0.1.7
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SERVER_HOST }}
|
||||||
|
username: ${{ secrets.SERVER_USER }}
|
||||||
|
key: ${{ secrets.SSH_KEY }}
|
||||||
|
source: "./dist/*"
|
||||||
|
target: ${{ env.REMOTE_DEPLOY_PATH }}
|
||||||
|
ssh_options: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
|
||||||
|
strip_components: 0
|
||||||
|
|
||||||
|
- name: 4. 远程重载 Nginx 配置
|
||||||
|
uses: appleboy/ssh-action@v1.0.3
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SERVER_HOST }}
|
||||||
|
username: ${{ secrets.SERVER_USER }}
|
||||||
|
key: ${{ secrets.SSH_KEY }}
|
||||||
|
# 核心:执行 Nginx 重载命令
|
||||||
|
script: |
|
||||||
|
echo "尝试重载 Nginx 服务..."
|
||||||
|
# 💡 注意:执行此命令需要服务器用户具有 sudo 权限,并且配置了 NOPASSWD。
|
||||||
|
# 否则工作流可能会因为权限不足而失败。
|
||||||
|
sudo systemctl reload nginx
|
||||||
|
echo "Nginx 重载命令已发送。"
|
||||||
|
|
||||||
|
- name: 5.发送构建结果邮件
|
||||||
|
if: always() # 无论上一步是否失败,都执行此步骤
|
||||||
|
uses: dawidd6/action-send-mail@v3
|
||||||
|
with:
|
||||||
|
|
||||||
|
from: ${{ secrets.MAIL_USERNAME }}
|
||||||
|
# --- 邮件配置 ---
|
||||||
|
server_address: smtp.gmail.com # 替换为你的SMTP服务器地址
|
||||||
|
server_port: 465 # 替换为你的SMTP端口 (通常是465或587)
|
||||||
|
username: ${{ secrets.MAIL_USERNAME }} # 存储在Secrets中的邮箱用户名
|
||||||
|
password: ${{ secrets.MAIL_PASSWORD }} # 存储在Secrets中的邮箱密码
|
||||||
|
subject: 'Gitea Actions 构建通知: ${{ job.status }} - AiDA back-java Develop'
|
||||||
|
# 收件人列表,可以根据需要更改
|
||||||
|
to: 'xupei3360@163.com,txli@aidlab.hk,cgzhou@aidlab.hk,zchengrong@yeah.net' # 替换为实际收件人邮箱
|
||||||
|
|
||||||
|
# --- 邮件正文内容 ---
|
||||||
|
body: |
|
||||||
|
项目: AiDA back-java Develop
|
||||||
|
分支: dev/3.1_release_merge
|
||||||
|
|
||||||
|
🎉 构建结果: ${{ job.status }}
|
||||||
|
|
||||||
|
📅 构建时间: ${{ steps.build_start_time.outputs.current_time }}
|
||||||
|
|
||||||
|
🔗 构建链接: ${{ gitea.server_url }}/${{ gitea.repository.owner.name }}/${{ gitea.repository.name }}/actions/runs/${{ gitea.run_id }}
|
||||||
|
|
||||||
|
# 确保邮件内容为纯文本,或者你可以设置为 html: true 并调整 body
|
||||||
|
content_type: text/plain
|
||||||
78
.gitea/workflows/prod_build_manual.yaml
Normal file
78
.gitea/workflows/prod_build_manual.yaml
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
name: AiDA WEB-Node.js 生产分支构建部署
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [ 18.18.0 ]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 0.记录开始时间
|
||||||
|
id: build_start_time
|
||||||
|
run: echo "current_time=$(TZ='Asia/Hong_Kong' date '+%Y-%m-%d %H:%M:%S %Z')" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: 1.检出代码
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: StableVersion
|
||||||
|
|
||||||
|
- name: 2.设置 Node.js 环境
|
||||||
|
uses: actions/setup-node@v6
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
- run: npm install
|
||||||
|
- run: npm run build
|
||||||
|
- run: ls -l
|
||||||
|
|
||||||
|
- name: 3.5. 手动安装 AWS CLI v2 # 新增步骤:确保 aws 命令可用
|
||||||
|
run: |
|
||||||
|
echo "安装 AWS CLI V2..."
|
||||||
|
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
|
||||||
|
unzip awscliv2.zip
|
||||||
|
sudo ./aws/install --update
|
||||||
|
aws --version
|
||||||
|
echo "AWS CLI V2 安装完成。"
|
||||||
|
|
||||||
|
- name: 4.配置 AWS 凭证
|
||||||
|
uses: aws-actions/configure-aws-credentials@main
|
||||||
|
with:
|
||||||
|
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
|
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
aws-region: 'ap-east-1'
|
||||||
|
|
||||||
|
- name: 5.同步 dist 目录到 S3
|
||||||
|
run: |
|
||||||
|
aws s3 sync dist/ s3://${{ secrets.S3_BUCKET_NAME }}/ --acl public-read
|
||||||
|
|
||||||
|
- name: 6.发送构建结果邮件
|
||||||
|
if: always() # 无论上一步是否失败,都执行此步骤
|
||||||
|
uses: dawidd6/action-send-mail@v3
|
||||||
|
with:
|
||||||
|
|
||||||
|
from: ${{ secrets.MAIL_USERNAME }}
|
||||||
|
# --- 邮件配置 ---
|
||||||
|
server_address: smtp.gmail.com # 替换为你的SMTP服务器地址
|
||||||
|
server_port: 465 # 替换为你的SMTP端口 (通常是465或587)
|
||||||
|
username: ${{ secrets.MAIL_USERNAME }} # 存储在Secrets中的邮箱用户名
|
||||||
|
password: ${{ secrets.MAIL_PASSWORD }} # 存储在Secrets中的邮箱密码
|
||||||
|
subject: 'Gitea Actions 构建通知: ${{ job.status }} - AiDA back-java Develop'
|
||||||
|
# 收件人列表,可以根据需要更改
|
||||||
|
to: 'xupei3360@163.com,txli@aidlab.hk,cgzhou@aidlab.hk,zchengrong@yeah.net' # 替换为实际收件人邮箱
|
||||||
|
|
||||||
|
# --- 邮件正文内容 ---
|
||||||
|
body: |
|
||||||
|
项目: AiDA back-java Develop
|
||||||
|
分支: dev/3.1_release_merge
|
||||||
|
|
||||||
|
🎉 构建结果: ${{ job.status }}
|
||||||
|
|
||||||
|
📅 构建时间: ${{ steps.build_start_time.outputs.current_time }}
|
||||||
|
|
||||||
|
🔗 构建链接: ${{ gitea.server_url }}/${{ gitea.repository.owner.name }}/${{ gitea.repository.name }}/actions/runs/${{ gitea.run_id }}
|
||||||
|
|
||||||
|
# 确保邮件内容为纯文本,或者你可以设置为 html: true 并调整 body
|
||||||
|
content_type: text/plain
|
||||||
81
.gitea/workflows/prod_build_schedule.yaml
Normal file
81
.gitea/workflows/prod_build_schedule.yaml
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
name: AiDA WEB-Node.js 生产分支构建部署
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
# cron为UTC时区,构建时间=部署时间-8小时 {*分 (-8)时 *日 *月 *周} ---
|
||||||
|
# 示例: 1月1日22点22分触发构建 cron写作 - '22 14 1 1 *'
|
||||||
|
- cron: '00 14 23 3 *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [ 18.18.0 ]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 0.记录开始时间
|
||||||
|
id: build_start_time
|
||||||
|
run: echo "current_time=$(TZ='Asia/Hong_Kong' date '+%Y-%m-%d %H:%M:%S %Z')" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: 1.检出代码
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: StableVersion
|
||||||
|
|
||||||
|
- name: 2.设置 Node.js 环境
|
||||||
|
uses: actions/setup-node@v6
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
- run: npm install
|
||||||
|
- run: npm run build
|
||||||
|
- run: ls -l
|
||||||
|
|
||||||
|
- name: 3.5. 手动安装 AWS CLI v2 # 新增步骤:确保 aws 命令可用
|
||||||
|
run: |
|
||||||
|
echo "安装 AWS CLI V2..."
|
||||||
|
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
|
||||||
|
unzip awscliv2.zip
|
||||||
|
sudo ./aws/install --update
|
||||||
|
aws --version
|
||||||
|
echo "AWS CLI V2 安装完成。"
|
||||||
|
|
||||||
|
- name: 4.配置 AWS 凭证
|
||||||
|
uses: aws-actions/configure-aws-credentials@main
|
||||||
|
with:
|
||||||
|
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
|
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
aws-region: 'ap-east-1'
|
||||||
|
|
||||||
|
- name: 5.同步 dist 目录到 S3
|
||||||
|
run: |
|
||||||
|
aws s3 sync dist/ s3://${{ secrets.S3_BUCKET_NAME }}/ --acl public-read
|
||||||
|
|
||||||
|
- name: 6.发送构建结果邮件
|
||||||
|
if: always() # 无论上一步是否失败,都执行此步骤
|
||||||
|
uses: dawidd6/action-send-mail@v3
|
||||||
|
with:
|
||||||
|
|
||||||
|
from: ${{ secrets.MAIL_USERNAME }}
|
||||||
|
# --- 邮件配置 ---
|
||||||
|
server_address: smtp.gmail.com # 替换为你的SMTP服务器地址
|
||||||
|
server_port: 465 # 替换为你的SMTP端口 (通常是465或587)
|
||||||
|
username: ${{ secrets.MAIL_USERNAME }} # 存储在Secrets中的邮箱用户名
|
||||||
|
password: ${{ secrets.MAIL_PASSWORD }} # 存储在Secrets中的邮箱密码
|
||||||
|
subject: 'Gitea Actions 构建通知: ${{ job.status }} - AiDA back-java Develop'
|
||||||
|
# 收件人列表,可以根据需要更改
|
||||||
|
to: 'cgzhou@aidlab.hk,zchengrong@yeah.net' # 替换为实际收件人邮箱
|
||||||
|
|
||||||
|
# --- 邮件正文内容 ---
|
||||||
|
body: |
|
||||||
|
项目: AiDA WEB-Node.js 生产分支构建部署
|
||||||
|
分支: StableVersion
|
||||||
|
|
||||||
|
🎉 构建结果: ${{ job.status }}
|
||||||
|
|
||||||
|
📅 构建时间: ${{ steps.build_start_time.outputs.current_time }}
|
||||||
|
|
||||||
|
🔗 构建链接: ${{ gitea.server_url }}/${{ gitea.repository.owner.name }}/${{ gitea.repository.name }}/actions/runs/${{ gitea.run_id }}
|
||||||
|
|
||||||
|
# 确保邮件内容为纯文本,或者你可以设置为 html: true 并调整 body
|
||||||
|
content_type: text/plain
|
||||||
85
.gitea/workflows/research_build_manual.yaml
Normal file
85
.gitea/workflows/research_build_manual.yaml
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
name: 手动触发 AiDA WEB-Node.js 开发分支构建部署
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [ 18.18.0 ]
|
||||||
|
env:
|
||||||
|
REMOTE_DEPLOY_PATH: /workspace/workspace_aida/Research/research-aida-web-front
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 0.记录开始时间
|
||||||
|
id: build_start_time
|
||||||
|
run: echo "current_time=$(TZ='Asia/Hong_Kong' date '+%Y-%m-%d %H:%M:%S %Z')" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: 1.检出代码
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: research
|
||||||
|
|
||||||
|
- name: 2.设置 Node.js 环境
|
||||||
|
uses: actions/setup-node@v6
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
- run: npm install
|
||||||
|
- run: npm run build:dev
|
||||||
|
- run: ls -l
|
||||||
|
|
||||||
|
- name: 3.同步文件到远程服务器
|
||||||
|
uses: appleboy/scp-action@v0.1.7
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SERVER_HOST }}
|
||||||
|
username: ${{ secrets.SERVER_USER }}
|
||||||
|
key: ${{ secrets.SSH_KEY }}
|
||||||
|
source: "./dist/*"
|
||||||
|
target: ${{ env.REMOTE_DEPLOY_PATH }}
|
||||||
|
ssh_options: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
|
||||||
|
strip_components: 0
|
||||||
|
|
||||||
|
- name: 4. 远程重载 Nginx 配置
|
||||||
|
uses: appleboy/ssh-action@v1.0.3
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.SERVER_HOST }}
|
||||||
|
username: ${{ secrets.SERVER_USER }}
|
||||||
|
key: ${{ secrets.SSH_KEY }}
|
||||||
|
# 核心:执行 Nginx 重载命令
|
||||||
|
script: |
|
||||||
|
echo "尝试重载 Nginx 服务..."
|
||||||
|
# 💡 注意:执行此命令需要服务器用户具有 sudo 权限,并且配置了 NOPASSWD。
|
||||||
|
# 否则工作流可能会因为权限不足而失败。
|
||||||
|
sudo systemctl reload nginx
|
||||||
|
echo "Nginx 重载命令已发送。"
|
||||||
|
|
||||||
|
- name: 5.发送构建结果邮件
|
||||||
|
if: always() # 无论上一步是否失败,都执行此步骤
|
||||||
|
uses: dawidd6/action-send-mail@v3
|
||||||
|
with:
|
||||||
|
|
||||||
|
from: ${{ secrets.MAIL_USERNAME }}
|
||||||
|
# --- 邮件配置 ---
|
||||||
|
server_address: smtp.gmail.com # 替换为你的SMTP服务器地址
|
||||||
|
server_port: 465 # 替换为你的SMTP端口 (通常是465或587)
|
||||||
|
username: ${{ secrets.MAIL_USERNAME }} # 存储在Secrets中的邮箱用户名
|
||||||
|
password: ${{ secrets.MAIL_PASSWORD }} # 存储在Secrets中的邮箱密码
|
||||||
|
subject: 'Gitea Actions 构建通知: ${{ job.status }} - AiDA back-java Develop'
|
||||||
|
# 收件人列表,可以根据需要更改
|
||||||
|
to: 'xupei3360@163.com,txli@aidlab.hk,cgzhou@aidlab.hk,zchengrong@yeah.net' # 替换为实际收件人邮箱
|
||||||
|
|
||||||
|
# --- 邮件正文内容 ---
|
||||||
|
body: |
|
||||||
|
项目: AiDA back-java Develop
|
||||||
|
分支: dev/3.1_release_merge
|
||||||
|
|
||||||
|
🎉 构建结果: ${{ job.status }}
|
||||||
|
|
||||||
|
📅 构建时间: ${{ steps.build_start_time.outputs.current_time }}
|
||||||
|
|
||||||
|
🔗 构建链接: ${{ gitea.server_url }}/${{ gitea.repository.owner.name }}/${{ gitea.repository.name }}/actions/runs/${{ gitea.run_id }}
|
||||||
|
|
||||||
|
# 确保邮件内容为纯文本,或者你可以设置为 html: true 并调整 body
|
||||||
|
content_type: text/plain
|
||||||
23
src/App.vue
23
src/App.vue
@@ -1,16 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<router-view/>
|
<router-view/>
|
||||||
<div class="loading" v-show="loading"><a-spin :delay="0.5" /></div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { computed } from 'vue';
|
|
||||||
import { useStore } from 'vuex';
|
|
||||||
const store = useStore();
|
|
||||||
const loading = computed(() => store.state.loading || store.state.view_loading);
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
#app {
|
#app {
|
||||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||||
@@ -18,19 +9,7 @@
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
.loading{
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: rgba(0,0,0,0.4);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
z-index: 999999999999;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.ipad{
|
.ipad{
|
||||||
*{
|
*{
|
||||||
-webkit-touch-callout:none;
|
-webkit-touch-callout:none;
|
||||||
|
|||||||
@@ -1250,14 +1250,10 @@ tr > .ant-picker-cell-in-view.ant-picker-cell-range-hover-start:last-child::afte
|
|||||||
background: #000 !important;
|
background: #000 !important;
|
||||||
border-color: #000 !important;
|
border-color: #000 !important;
|
||||||
}
|
}
|
||||||
.ant-spin .ant-spin-dot {
|
|
||||||
width: 1.5em;
|
|
||||||
height: 1.5em;
|
|
||||||
}
|
|
||||||
.ant-spin-dot-item {
|
.ant-spin-dot-item {
|
||||||
background-color: #000000 !important;
|
background-color: #000000 !important;
|
||||||
width: 0.9em !important;
|
width: 9px !important;
|
||||||
height: 0.9em !important;
|
height: 9px !important;
|
||||||
}
|
}
|
||||||
.ant-spin {
|
.ant-spin {
|
||||||
color: #000;
|
color: #000;
|
||||||
|
|||||||
@@ -1378,14 +1378,10 @@ tr > .ant-picker-cell-in-view.ant-picker-cell-range-hover-start:last-child::afte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//loding样式
|
//loding样式
|
||||||
.ant-spin .ant-spin-dot{
|
|
||||||
width: 1.5em;
|
|
||||||
height: 1.5em;
|
|
||||||
}
|
|
||||||
.ant-spin-dot-item{
|
.ant-spin-dot-item{
|
||||||
background-color: #000000 !important;
|
background-color: #000000 !important;
|
||||||
width: .9em !important;
|
width: 9px !important;
|
||||||
height: .9em !important;
|
height: 9px !important;
|
||||||
}
|
}
|
||||||
.ant-spin{
|
.ant-spin{
|
||||||
color: #000;
|
color: #000;
|
||||||
|
|||||||
@@ -1,848 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="subscription-plan">
|
|
||||||
<a-card class="search-card" :bordered="false">
|
|
||||||
<a-form
|
|
||||||
class="search-form"
|
|
||||||
layout="inline"
|
|
||||||
:model="searchForm"
|
|
||||||
:label-col="{ style: { width: '12rem' } }"
|
|
||||||
:wrapper-col="{ style: { width: '22rem' } }"
|
|
||||||
>
|
|
||||||
<a-form-item label="ID">
|
|
||||||
<a-input v-model:value="searchForm.id" allow-clear placeholder="Input the id" />
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="Name">
|
|
||||||
<a-input
|
|
||||||
v-model:value="searchForm.name"
|
|
||||||
allow-clear
|
|
||||||
placeholder="Input the name"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="Time Range">
|
|
||||||
<a-range-picker
|
|
||||||
v-model:value="searchForm.dateRange"
|
|
||||||
value-format="X"
|
|
||||||
allow-clear
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="Organization">
|
|
||||||
<a-select
|
|
||||||
v-model:value="searchForm.organizationId"
|
|
||||||
allow-clear
|
|
||||||
placeholder="Select Organization"
|
|
||||||
style="width: 180px"
|
|
||||||
@popupScroll="handleOrganizationScroll"
|
|
||||||
@select="handleOrganizationSelect"
|
|
||||||
@change="handleOrganizationChange"
|
|
||||||
>
|
|
||||||
<a-select-option value="ADD_ORGANIZATION" class="add-organization-option">
|
|
||||||
+ 添加组织
|
|
||||||
</a-select-option>
|
|
||||||
<a-select-option
|
|
||||||
v-for="item in organizationOptions"
|
|
||||||
:key="item.id"
|
|
||||||
:value="item.id"
|
|
||||||
>
|
|
||||||
{{ item.name }}
|
|
||||||
</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="Admin Account">
|
|
||||||
<a-select
|
|
||||||
v-model:value="searchForm.adminAccId"
|
|
||||||
allow-clear
|
|
||||||
show-search
|
|
||||||
:filter-option="filterOption"
|
|
||||||
placeholder="Select Account"
|
|
||||||
style="width: 180px"
|
|
||||||
:options="allUserList"
|
|
||||||
></a-select>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item>
|
|
||||||
<a-space>
|
|
||||||
<a-button type="primary" @click="handleSearch">Search</a-button>
|
|
||||||
<a-button @click="handleReset">Reset</a-button>
|
|
||||||
</a-space>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
|
||||||
</a-card>
|
|
||||||
|
|
||||||
<a-card class="table-card" :bordered="false">
|
|
||||||
<div class="table-card__header">
|
|
||||||
<div class="table-card__title">Subscription Plan</div>
|
|
||||||
<a-button type="primary" @click="openCreate">New Subscription Plan</a-button>
|
|
||||||
</div>
|
|
||||||
<a-table
|
|
||||||
:data-source="tableData"
|
|
||||||
:columns="columns"
|
|
||||||
:loading="tableLoading"
|
|
||||||
row-key="id"
|
|
||||||
:pagination="{
|
|
||||||
showSizeChanger: true,
|
|
||||||
current: searchForm.page,
|
|
||||||
pageSize: searchForm.size,
|
|
||||||
total: searchForm.total,
|
|
||||||
showQuickJumper: true,
|
|
||||||
bordered: false
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<template #bodyCell="{ column, record }">
|
|
||||||
<template
|
|
||||||
v-if="
|
|
||||||
column.key === 'currentPeriodStart' || column.key === 'currentPeriodEnd'
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{{ formatTime(record[column.key], 'YYYY-MM-DD hh:mm:ss') }}
|
|
||||||
</template>
|
|
||||||
<!-- <template v-if="column.key === 'organizationId'">
|
|
||||||
{{ organizationOptions.find(item => item.id === record[column.key]).name }}
|
|
||||||
</template> -->
|
|
||||||
|
|
||||||
<template v-if="column.key === 'status'">
|
|
||||||
<a-tag :color="statusColorMap[record.status]">
|
|
||||||
{{ statusLabelMap[record.status] }}
|
|
||||||
</a-tag>
|
|
||||||
</template>
|
|
||||||
<template v-if="column.key === 'adminAccId'">
|
|
||||||
{{ allUserList.find(item => item.value === record.adminAccId)?.label }}
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-else-if="column.key === 'actions'">
|
|
||||||
<a-space>
|
|
||||||
<a @click="openEdit(record)">Edit</a>
|
|
||||||
<a-popconfirm
|
|
||||||
title="Confirm to delete this subscription plan?"
|
|
||||||
ok-text="Confirm"
|
|
||||||
cancel-text="Cancel"
|
|
||||||
@confirm="removePlan(record.id)"
|
|
||||||
>
|
|
||||||
<a class="danger-text">Delete</a>
|
|
||||||
</a-popconfirm>
|
|
||||||
</a-space>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</a-table>
|
|
||||||
</a-card>
|
|
||||||
|
|
||||||
<div class="subscriptionPlanModal" ref="subscriptionPlanModal"></div>
|
|
||||||
<a-modal
|
|
||||||
class="subscriptionPlan_modal generalModel"
|
|
||||||
v-model:visible="modalVisible"
|
|
||||||
:footer="null"
|
|
||||||
:get-container="() => $refs.subscriptionPlanModal"
|
|
||||||
width="50%"
|
|
||||||
:maskClosable="false"
|
|
||||||
:centered="true"
|
|
||||||
:closable="false"
|
|
||||||
:mask="true"
|
|
||||||
wrapClassName="#app"
|
|
||||||
:keyboard="false"
|
|
||||||
destroy-on-close
|
|
||||||
>
|
|
||||||
<div class="generalModel_btn">
|
|
||||||
<div class="generalModel_closeIcon" @click.stop="cancelModal">
|
|
||||||
<svg
|
|
||||||
width="100%"
|
|
||||||
height="100%"
|
|
||||||
viewBox="0 0 46 46"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<circle cx="23" cy="23" r="23" fill="#000" fill-opacity="0.3" />
|
|
||||||
<rect
|
|
||||||
x="32.5063"
|
|
||||||
y="12"
|
|
||||||
width="3"
|
|
||||||
height="29"
|
|
||||||
rx="1.5"
|
|
||||||
transform="rotate(45 32.5063 12)"
|
|
||||||
fill="white"
|
|
||||||
/>
|
|
||||||
<rect
|
|
||||||
x="34.6274"
|
|
||||||
y="32.5059"
|
|
||||||
width="3"
|
|
||||||
height="29"
|
|
||||||
rx="1.5"
|
|
||||||
transform="rotate(135 34.6274 32.5059)"
|
|
||||||
fill="white"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal_title_text">
|
|
||||||
<div>{{ modalTitle }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="subscriptionPlan_center admin_page">
|
|
||||||
<div class="form_content">
|
|
||||||
<div class="admin_state_item">
|
|
||||||
<span>
|
|
||||||
Name:
|
|
||||||
<span>*</span>
|
|
||||||
</span>
|
|
||||||
<a-input
|
|
||||||
v-model:value="formState.name"
|
|
||||||
placeholder="Input the name"
|
|
||||||
style="width: 250px"
|
|
||||||
:disabled="isEditMode"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="admin_state_item">
|
|
||||||
<span>
|
|
||||||
Organization:
|
|
||||||
<span>*</span>
|
|
||||||
</span>
|
|
||||||
<a-select
|
|
||||||
v-model:value="formState.organizationId"
|
|
||||||
placeholder="Select the organization"
|
|
||||||
allow-clear
|
|
||||||
style="width: 250px"
|
|
||||||
@popupScroll="handleOrganizationScroll"
|
|
||||||
@select="handleOrganizationSelect"
|
|
||||||
@change="handleOrganizationChange"
|
|
||||||
:disabled="isEditMode"
|
|
||||||
>
|
|
||||||
<a-select-option value="ADD_ORGANIZATION" class="add-organization-option">
|
|
||||||
+ 添加组织
|
|
||||||
</a-select-option>
|
|
||||||
<a-select-option
|
|
||||||
v-for="item in organizationOptions"
|
|
||||||
:key="item.id"
|
|
||||||
:value="item.id"
|
|
||||||
>
|
|
||||||
{{ item.name }}
|
|
||||||
</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</div>
|
|
||||||
<div class="admin_state_item">
|
|
||||||
<span>
|
|
||||||
Admin Account:
|
|
||||||
<span>*</span>
|
|
||||||
</span>
|
|
||||||
<a-select
|
|
||||||
v-model:value="formState.adminAccId"
|
|
||||||
placeholder="Select the admin account"
|
|
||||||
allow-clear
|
|
||||||
show-search
|
|
||||||
:filter-option="filterOption"
|
|
||||||
style="width: 250px"
|
|
||||||
:options="allUserList"
|
|
||||||
></a-select>
|
|
||||||
</div>
|
|
||||||
<div class="admin_state_item">
|
|
||||||
<span>
|
|
||||||
Start Time:
|
|
||||||
<span>*</span>
|
|
||||||
</span>
|
|
||||||
<a-date-picker
|
|
||||||
v-model:value="formState.currentPeriodStart"
|
|
||||||
value-format="X"
|
|
||||||
style="width: 250px"
|
|
||||||
class="range_picker"
|
|
||||||
placeholder="Select the start time"
|
|
||||||
>
|
|
||||||
<template #suffixIcon>
|
|
||||||
<span class="icon iconfont range_picker_icon icon-rili"></span>
|
|
||||||
</template>
|
|
||||||
</a-date-picker>
|
|
||||||
</div>
|
|
||||||
<div class="admin_state_item">
|
|
||||||
<span>
|
|
||||||
End Time:
|
|
||||||
<span>*</span>
|
|
||||||
</span>
|
|
||||||
<a-date-picker
|
|
||||||
v-model:value="formState.currentPeriodEnd"
|
|
||||||
value-format="X"
|
|
||||||
style="width: 250px"
|
|
||||||
class="range_picker"
|
|
||||||
placeholder="Select the end time"
|
|
||||||
>
|
|
||||||
<template #suffixIcon>
|
|
||||||
<span class="icon iconfont range_picker_icon icon-rili"></span>
|
|
||||||
</template>
|
|
||||||
</a-date-picker>
|
|
||||||
</div>
|
|
||||||
<div class="admin_state_item">
|
|
||||||
<span>
|
|
||||||
Account Num:
|
|
||||||
<span>*</span>
|
|
||||||
</span>
|
|
||||||
<a-input-number
|
|
||||||
v-model:value="formState.accountNum"
|
|
||||||
:min="0"
|
|
||||||
style="width: 250px"
|
|
||||||
placeholder="Input the account number"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="admin_state_item">
|
|
||||||
<span>
|
|
||||||
Credit Limit:
|
|
||||||
<span>*</span>
|
|
||||||
</span>
|
|
||||||
<a-input-number
|
|
||||||
v-model:value="formState.creditLimit"
|
|
||||||
:min="0"
|
|
||||||
style="width: 250px"
|
|
||||||
placeholder="Input the credit limit"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="subscriptionPlan_btn admin_page">
|
|
||||||
<div class="admin_search_item" @click="cancelModal">Close</div>
|
|
||||||
<div class="admin_search_item" @click="handleSubmit">OK</div>
|
|
||||||
</div>
|
|
||||||
</a-modal>
|
|
||||||
|
|
||||||
<div class="organizationModal" ref="organizationModal"></div>
|
|
||||||
<a-modal
|
|
||||||
class="organization_modal"
|
|
||||||
v-model:visible="organizationModalVisible"
|
|
||||||
:footer="null"
|
|
||||||
:get-container="() => $refs.organizationModal"
|
|
||||||
:maskClosable="false"
|
|
||||||
:centered="true"
|
|
||||||
:mask="true"
|
|
||||||
wrapClassName="#app"
|
|
||||||
:keyboard="false"
|
|
||||||
destroy-on-close
|
|
||||||
>
|
|
||||||
<div class="modal_title_text">
|
|
||||||
<div>Create Organization</div>
|
|
||||||
</div>
|
|
||||||
<div class="subscriptionPlan_center admin_page">
|
|
||||||
<div class="form_content">
|
|
||||||
<div class="admin_state_item">
|
|
||||||
<span>
|
|
||||||
Name:
|
|
||||||
<span>*</span>
|
|
||||||
</span>
|
|
||||||
<a-input
|
|
||||||
v-model:value="organizationForm.name"
|
|
||||||
placeholder="Input the name"
|
|
||||||
style="width: 250px"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="admin_state_item">
|
|
||||||
<span>
|
|
||||||
Type:
|
|
||||||
<span>*</span>
|
|
||||||
</span>
|
|
||||||
<a-select
|
|
||||||
v-model:value="organizationForm.type"
|
|
||||||
placeholder="Select type"
|
|
||||||
style="width: 250px"
|
|
||||||
>
|
|
||||||
<a-select-option value="Enterprise">Enterprise</a-select-option>
|
|
||||||
<a-select-option value="Education">Education</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="organization_footer">
|
|
||||||
<div class="footer_btn ant-btn ant-btn-primary" @click="cancelOrganizationModal">
|
|
||||||
Close
|
|
||||||
</div>
|
|
||||||
<div class="footer_btn ant-btn ant-btn-primary" @click="handleCreateOrganization">
|
|
||||||
OK
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a-modal>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { reactive, ref, onMounted, computed, nextTick } from 'vue'
|
|
||||||
import { message } from 'ant-design-vue'
|
|
||||||
import { Https } from '@/tool/https'
|
|
||||||
import { formatTime } from '@/tool/util'
|
|
||||||
import store from '@/store'
|
|
||||||
import type { FormInstance, Rule } from 'ant-design-vue/es/form'
|
|
||||||
|
|
||||||
type PlanStatus = 'active' | 'paused' | 'ended'
|
|
||||||
interface SubscriptionPlan {
|
|
||||||
id: number
|
|
||||||
name: string
|
|
||||||
currentPeriodStart: string
|
|
||||||
currentPeriodEnd: string
|
|
||||||
organizationId: string
|
|
||||||
adminAccId: string
|
|
||||||
status: PlanStatus
|
|
||||||
creditLimit: number
|
|
||||||
accountNum?: number
|
|
||||||
startStamp: number
|
|
||||||
endStamp: number
|
|
||||||
}
|
|
||||||
|
|
||||||
const searchForm = reactive({
|
|
||||||
name: '',
|
|
||||||
startTime: '',
|
|
||||||
endTime: '',
|
|
||||||
organizationId: undefined as string | undefined,
|
|
||||||
adminAccId: undefined as string | undefined,
|
|
||||||
id: '',
|
|
||||||
page: 1,
|
|
||||||
size: 10,
|
|
||||||
total: 0
|
|
||||||
})
|
|
||||||
|
|
||||||
const toSeconds = (dateStr: string) => Math.floor(new Date(dateStr).getTime() / 1000)
|
|
||||||
|
|
||||||
const tableData = ref<SubscriptionPlan[]>([])
|
|
||||||
const tableLoading = ref(false)
|
|
||||||
|
|
||||||
const modalVisible = ref(false)
|
|
||||||
const confirmLoading = ref(false)
|
|
||||||
const modalTitle = ref('New Subscription Plan')
|
|
||||||
const isEditMode = ref(false)
|
|
||||||
const formState = reactive({
|
|
||||||
name: '',
|
|
||||||
currentPeriodStart: '',
|
|
||||||
currentPeriodEnd: '',
|
|
||||||
organizationId: undefined as string | undefined,
|
|
||||||
adminAccId: undefined as string | undefined,
|
|
||||||
creditLimit: null as number | null,
|
|
||||||
accountNum: null as number | null
|
|
||||||
})
|
|
||||||
|
|
||||||
const organizationModalVisible = ref(false)
|
|
||||||
const organizationForm = reactive({
|
|
||||||
name: '',
|
|
||||||
type: undefined as string | undefined
|
|
||||||
})
|
|
||||||
|
|
||||||
const statusLabelMap: Record<PlanStatus, string> = {
|
|
||||||
active: 'Active',
|
|
||||||
paused: 'Paused',
|
|
||||||
ended: 'Ended'
|
|
||||||
}
|
|
||||||
const statusColorMap: Record<PlanStatus, string> = {
|
|
||||||
active: 'green',
|
|
||||||
paused: 'orange',
|
|
||||||
ended: 'red'
|
|
||||||
}
|
|
||||||
|
|
||||||
const columns = [
|
|
||||||
{ title: 'Name', dataIndex: 'name', key: 'name' },
|
|
||||||
{ title: 'ID', dataIndex: 'id', key: 'id' },
|
|
||||||
{ title: 'Organization', dataIndex: 'organizationName', key: 'organizationName' },
|
|
||||||
{ title: 'Admin Account', dataIndex: 'adminAccId', key: 'adminAccId' },
|
|
||||||
{ title: 'Account Num', dataIndex: 'accountNum', key: 'accountNum' },
|
|
||||||
{
|
|
||||||
title: 'Start Time',
|
|
||||||
dataIndex: 'currentPeriodStart',
|
|
||||||
key: 'currentPeriodStart'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'End Time',
|
|
||||||
dataIndex: 'currentPeriodEnd',
|
|
||||||
key: 'currentPeriodEnd'
|
|
||||||
},
|
|
||||||
{ title: 'Status', dataIndex: 'status', key: 'status' },
|
|
||||||
{ title: 'Credit Limit', dataIndex: 'creditLimit', key: 'creditLimit' },
|
|
||||||
{ title: 'Operations', key: 'actions', width: 160 }
|
|
||||||
]
|
|
||||||
onMounted(async () => {
|
|
||||||
await getOrganizationList()
|
|
||||||
await handleSearch()
|
|
||||||
})
|
|
||||||
|
|
||||||
const handleFetchTableData = async () => {
|
|
||||||
tableLoading.value = true
|
|
||||||
return Https.axiosPost(Https.httpUrls.searchAllSubscribePlan, searchForm)
|
|
||||||
.then(res => {
|
|
||||||
tableData.value = res.records.map(item => {
|
|
||||||
const organization = organizationOptions.value.find(
|
|
||||||
el => el.id === item.organizationId
|
|
||||||
) || { name: '' }
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
organizationName: organization.name || ''
|
|
||||||
}
|
|
||||||
debugger
|
|
||||||
})
|
|
||||||
searchForm.total = res.total
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
tableLoading.value = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const resetFormState = () => {
|
|
||||||
formState.name = ''
|
|
||||||
formState.currentPeriodStart = ''
|
|
||||||
formState.currentPeriodEnd = ''
|
|
||||||
formState.organizationId = undefined
|
|
||||||
formState.adminAccId = undefined
|
|
||||||
formState.creditLimit = null
|
|
||||||
formState.accountNum = null
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSearch = () => {
|
|
||||||
searchForm.page = 1
|
|
||||||
handleFetchTableData()
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleReset = () => {
|
|
||||||
searchForm.name = ''
|
|
||||||
searchForm.startTime = ''
|
|
||||||
searchForm.endTime = ''
|
|
||||||
searchForm.organizationId = undefined
|
|
||||||
searchForm.adminAccId = undefined
|
|
||||||
searchForm.id = ''
|
|
||||||
handleSearch()
|
|
||||||
}
|
|
||||||
|
|
||||||
const allUserList = computed(() => {
|
|
||||||
return store.state.adminPage.allUserList
|
|
||||||
})
|
|
||||||
const openCreate = () => {
|
|
||||||
modalTitle.value = 'New Subscription Plan'
|
|
||||||
isEditMode.value = false
|
|
||||||
resetFormState()
|
|
||||||
modalVisible.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const openEdit = (record: SubscriptionPlan) => {
|
|
||||||
modalTitle.value = 'Edit Subscription Plan'
|
|
||||||
isEditMode.value = true
|
|
||||||
formState.name = record.name
|
|
||||||
formState.currentPeriodStart = record.currentPeriodStart
|
|
||||||
formState.currentPeriodEnd = record.currentPeriodEnd
|
|
||||||
formState.organizationId = record.organizationId
|
|
||||||
formState.adminAccId = record.adminAccId
|
|
||||||
formState.creditLimit = record.creditLimit
|
|
||||||
formState.accountNum = (record as any).accountNum || null
|
|
||||||
modalVisible.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const validateForm = (): boolean => {
|
|
||||||
interface FieldRule {
|
|
||||||
value: any
|
|
||||||
message: string
|
|
||||||
checkNull?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
const requiredFields: FieldRule[] = [
|
|
||||||
{ value: formState.currentPeriodStart, message: 'Please select the start time' },
|
|
||||||
{ value: formState.currentPeriodEnd, message: 'Please select the end time' },
|
|
||||||
{ value: formState.adminAccId, message: 'Please select the admin account' },
|
|
||||||
{
|
|
||||||
value: formState.creditLimit,
|
|
||||||
message: 'Please input credit limit',
|
|
||||||
checkNull: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: formState.accountNum,
|
|
||||||
message: 'Please input account number',
|
|
||||||
checkNull: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
if (!isEditMode.value) {
|
|
||||||
requiredFields.push(
|
|
||||||
{ value: formState.name, message: 'Please input the name' },
|
|
||||||
{ value: formState.organizationId, message: 'Please select organization' }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const field of requiredFields) {
|
|
||||||
const isEmpty = field.checkNull
|
|
||||||
? field.value === null || field.value === undefined
|
|
||||||
: !field.value
|
|
||||||
if (isEmpty) {
|
|
||||||
message.warning(field.message)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
if (!validateForm()) return
|
|
||||||
confirmLoading.value = true
|
|
||||||
const params = {
|
|
||||||
...formState,
|
|
||||||
currentPeriodStart: Number(formState.currentPeriodStart),
|
|
||||||
currentPeriodEnd: Number(formState.currentPeriodEnd)
|
|
||||||
}
|
|
||||||
let res = null
|
|
||||||
try {
|
|
||||||
if (isEditMode.value) {
|
|
||||||
res = await Https.axiosPost(Https.httpUrls.updateSubscribePlan, params)
|
|
||||||
} else {
|
|
||||||
res = await Https.axiosPost(Https.httpUrls.createSubscribePlan, params)
|
|
||||||
}
|
|
||||||
message.success(
|
|
||||||
`${isEditMode.value ? 'Subscription plan updated' : 'Subscription plan created'}`
|
|
||||||
)
|
|
||||||
} catch (error: any) {
|
|
||||||
message.error(error.message)
|
|
||||||
console.error(error)
|
|
||||||
} finally {
|
|
||||||
confirmLoading.value = false
|
|
||||||
modalVisible.value = false
|
|
||||||
resetFormState()
|
|
||||||
isEditMode.value = false
|
|
||||||
handleSearch()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const cancelModal = () => {
|
|
||||||
modalVisible.value = false
|
|
||||||
resetFormState()
|
|
||||||
isEditMode.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const removePlan = (id: number) => {
|
|
||||||
tableLoading.value = true
|
|
||||||
Https.axiosGet(Https.httpUrls.deleteSubscribePlan, { params: { id } })
|
|
||||||
.then(res => {
|
|
||||||
message.success('Subscription plan deleted')
|
|
||||||
handleReset()
|
|
||||||
})
|
|
||||||
.catch((error: any) => {
|
|
||||||
message.error(error.message)
|
|
||||||
console.error(error)
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
tableLoading.value = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const organizationOptions = ref([])
|
|
||||||
const organizationParams = reactive({
|
|
||||||
page: 1,
|
|
||||||
size: 10,
|
|
||||||
total: 0
|
|
||||||
})
|
|
||||||
const organizationLoading = ref(false)
|
|
||||||
const getOrganizationList = async (isLoadMore = false) => {
|
|
||||||
if (organizationLoading.value) return
|
|
||||||
if (isLoadMore) {
|
|
||||||
const loaded = organizationParams.page * organizationParams.size
|
|
||||||
if (organizationParams.total && loaded >= organizationParams.total) return
|
|
||||||
organizationParams.page += 1
|
|
||||||
} else {
|
|
||||||
organizationParams.page = 1
|
|
||||||
organizationOptions.value = []
|
|
||||||
}
|
|
||||||
organizationLoading.value = true
|
|
||||||
try {
|
|
||||||
const rv: any = await Https.axiosPost(
|
|
||||||
Https.httpUrls.queryOrganization,
|
|
||||||
organizationParams
|
|
||||||
)
|
|
||||||
if (rv) {
|
|
||||||
organizationOptions.value = [...organizationOptions.value, ...(rv.records || [])]
|
|
||||||
organizationParams.total = rv.total || 0
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
organizationLoading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const handleOrganizationScroll = (e: any) => {
|
|
||||||
const target = e?.target
|
|
||||||
if (!target) return
|
|
||||||
const nearBottom = target.scrollTop + target.clientHeight >= target.scrollHeight - 20
|
|
||||||
if (nearBottom) {
|
|
||||||
getOrganizationList(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleOrganizationSelect = (value: string) => {
|
|
||||||
if (value === 'ADD_ORGANIZATION') {
|
|
||||||
// 打开添加组织弹窗
|
|
||||||
organizationModalVisible.value = true
|
|
||||||
// 使用nextTick确保值被重置,使其不被选中
|
|
||||||
nextTick(() => {
|
|
||||||
if (searchForm.organizationId === 'ADD_ORGANIZATION') {
|
|
||||||
searchForm.organizationId = undefined
|
|
||||||
}
|
|
||||||
if (formState.organizationId === 'ADD_ORGANIZATION') {
|
|
||||||
formState.organizationId = undefined
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleOrganizationChange = (value: string) => {
|
|
||||||
// 如果change事件触发时值是"添加组织",立即重置
|
|
||||||
if (value === 'ADD_ORGANIZATION') {
|
|
||||||
nextTick(() => {
|
|
||||||
if (searchForm.organizationId === 'ADD_ORGANIZATION') {
|
|
||||||
searchForm.organizationId = undefined
|
|
||||||
}
|
|
||||||
if (formState.organizationId === 'ADD_ORGANIZATION') {
|
|
||||||
formState.organizationId = undefined
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const cancelOrganizationModal = () => {
|
|
||||||
organizationModalVisible.value = false
|
|
||||||
organizationForm.name = ''
|
|
||||||
organizationForm.type = undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleCreateOrganization = async () => {
|
|
||||||
if (!organizationForm.name || !organizationForm.type) {
|
|
||||||
message.warning('Please fill in name and type')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const res: any = await Https.axiosGet(Https.httpUrls.addOrganization, {
|
|
||||||
params: {
|
|
||||||
name: organizationForm.name,
|
|
||||||
type: organizationForm.type
|
|
||||||
}
|
|
||||||
})
|
|
||||||
message.success('Organization created successfully')
|
|
||||||
cancelOrganizationModal()
|
|
||||||
// 刷新组织列表
|
|
||||||
await getOrganizationList()
|
|
||||||
// 如果是在编辑/新建弹窗中,自动选择新创建的组织
|
|
||||||
if (modalVisible.value) {
|
|
||||||
const newOrgId = res?.id || res?.data?.id || res
|
|
||||||
if (newOrgId) {
|
|
||||||
formState.organizationId = String(newOrgId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error: any) {
|
|
||||||
message.error(error.message || 'Failed to create organization')
|
|
||||||
console.error(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const filterOption = (input: string, option: any) => {
|
|
||||||
const label = option?.label ?? option?.children ?? option?.key?.label ?? ''
|
|
||||||
return String(label).toLowerCase().includes(input.toLowerCase())
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.subscription-plan {
|
|
||||||
padding: 20px 24px 32px 0;
|
|
||||||
|
|
||||||
.search-card {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-card {
|
|
||||||
.table-card__header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
|
|
||||||
.table-card__title {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.danger-text {
|
|
||||||
color: #ff4d4f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:deep(.subscriptionPlan_modal) {
|
|
||||||
.ant-modal-body {
|
|
||||||
height: calc(65rem * 1.2);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 2.5rem 3rem;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.subscriptionPlan_modal {
|
|
||||||
> .admin_state_item {
|
|
||||||
> span {
|
|
||||||
width: 15rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.modal_title_text {
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
.subscriptionPlan_center {
|
|
||||||
flex: 1;
|
|
||||||
overflow-y: auto;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 2rem 0;
|
|
||||||
}
|
|
||||||
.subscriptionPlan_btn {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
height: auto;
|
|
||||||
justify-content: flex-end;
|
|
||||||
padding: 1.5rem 0 0 0;
|
|
||||||
margin-top: auto;
|
|
||||||
flex-shrink: 0;
|
|
||||||
.admin_search_item {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.search-form) {
|
|
||||||
column-gap: 2rem;
|
|
||||||
row-gap: 2rem;
|
|
||||||
.ant-select {
|
|
||||||
width: 100% !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.ant-select-dropdown) {
|
|
||||||
.add-organization-option {
|
|
||||||
color: #1890ff !important;
|
|
||||||
font-weight: 600;
|
|
||||||
background-color: #f0f7ff !important;
|
|
||||||
border-bottom: 1px solid #e6f4ff;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
padding-bottom: 4px;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: #e6f4ff !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.organization_modal) {
|
|
||||||
.ant-modal-body {
|
|
||||||
height: auto;
|
|
||||||
min-height: 300px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 2rem 2.5rem;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subscriptionPlan_center {
|
|
||||||
flex: 0 0 auto;
|
|
||||||
overflow: visible;
|
|
||||||
padding: 1rem 0;
|
|
||||||
min-height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal_title_text {
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.organization_footer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
column-gap: 3rem;
|
|
||||||
.footer_btn {
|
|
||||||
border-radius: 3.3rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -34,8 +34,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layout_centent" :class="{active:flex_direction}" id="layoutCentent">
|
<div class="layout_centent" :class="{active:flex_direction}" id="layoutCentent">
|
||||||
<div v-for="item,index in layoutList" :key="item" :class="moodbClassName[index]" class="modal_imgItem" v-layout="item" @mousedown="setpitch(item,index)" @touchstart="setpitch(item,index)" ref="content" :style="{'background-image':`url(${item.imgUrl})`,'transform':`scale(${item.zoom?item.zoom:1}) rotateZ(${item.angle?item.angle:0}deg)`}">
|
<div v-for="item,index in layoutList" :key="item" :class="moodbClassName[index]" class="modal_imgItem" v-layout="item" @mousedown="setpitch(item,index)" @touchstart="setpitch(item,index)" ref="content" >
|
||||||
<!-- <img crossOrigin="anonymous" :src="item.imgUrl" :style="{'transform':`translate(-50%, -50%) scale(${item.zoom?item.zoom:1}) rotateZ(${item.angle?item.angle:0}deg)`}" draggable="false" :class="moodbClassName[index]" v-modelImg> -->
|
<img crossOrigin="anonymous" :src="item.imgUrl" :style="{'transform':`translate(-50%, -50%) scale(${item.zoom?item.zoom:1}) rotateZ(${item.angle?item.angle:0}deg)`}" draggable="false" :class="moodbClassName[index]" v-modelImg>
|
||||||
<ul v-show="item.setPitch" class="layout_btn" >
|
<ul v-show="item.setPitch" class="layout_btn" >
|
||||||
<li class="layout_btn_top" v-compile.stop="'top'"></li>
|
<li class="layout_btn_top" v-compile.stop="'top'"></li>
|
||||||
<li class="layout_btn_bottom" v-compile.stop="'bottom'"></li>
|
<li class="layout_btn_bottom" v-compile.stop="'bottom'"></li>
|
||||||
@@ -736,7 +736,6 @@ export default defineComponent({
|
|||||||
setmoodb(item:any){
|
setmoodb(item:any){
|
||||||
this.moodbClassName = item
|
this.moodbClassName = item
|
||||||
this.$emit('setmoodbClass',this.moodbClassName)
|
this.$emit('setmoodbClass',this.moodbClassName)
|
||||||
this.styleObj.class = this.moodbClassName
|
|
||||||
if(this.content){
|
if(this.content){
|
||||||
for (item of (this.content as any)) {
|
for (item of (this.content as any)) {
|
||||||
item.classList.remove('active')
|
item.classList.remove('active')
|
||||||
@@ -773,7 +772,7 @@ export default defineComponent({
|
|||||||
initDomStyle(){
|
initDomStyle(){
|
||||||
nextTick(()=>{
|
nextTick(()=>{
|
||||||
this.content.forEach((item:any,index:any) => {
|
this.content.forEach((item:any,index:any) => {
|
||||||
if(this.styleObj.domStyle[index]?.left){
|
if(this.styleObj.domStyle[index]){
|
||||||
item.classList.add('active')
|
item.classList.add('active')
|
||||||
this.initStyle(item,this.styleObj.domStyle[index])
|
this.initStyle(item,this.styleObj.domStyle[index])
|
||||||
}
|
}
|
||||||
@@ -795,7 +794,7 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
initStyle(dom:any,style:any){
|
initStyle(dom:any,style:any){
|
||||||
if(!style || !dom)return
|
if(!style)return
|
||||||
for (const [property, value] of Object.entries(style)) {
|
for (const [property, value] of Object.entries(style)) {
|
||||||
|
|
||||||
dom.style.setProperty(property, value);
|
dom.style.setProperty(property, value);
|
||||||
@@ -807,7 +806,7 @@ export default defineComponent({
|
|||||||
this.styleObj.domStyle.push(this.setStyle(item.style))
|
this.styleObj.domStyle.push(this.setStyle(item.style))
|
||||||
this.domObj.dom.forEach((domName:any,index:any) => {
|
this.domObj.dom.forEach((domName:any,index:any) => {
|
||||||
let style = this.domObj.domStyle[index]
|
let style = this.domObj.domStyle[index]
|
||||||
let dom = item.querySelector(domName) || item
|
let dom = item.querySelector(domName)
|
||||||
this.styleObj[style].push(this.setStyle(dom.style))
|
this.styleObj[style].push(this.setStyle(dom.style))
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@@ -841,6 +840,7 @@ export default defineComponent({
|
|||||||
let config:any = {headers:{'Content-Type':'multipart/form-data','Accept':'*/*' }}
|
let config:any = {headers:{'Content-Type':'multipart/form-data','Accept':'*/*' }}
|
||||||
Https.axiosPost(Https.httpUrls.elementUpload,param,config)
|
Https.axiosPost(Https.httpUrls.elementUpload,param,config)
|
||||||
.then((rv: any) => {
|
.then((rv: any) => {
|
||||||
|
// console.log(rv);
|
||||||
rv.imgUrl = rv.url
|
rv.imgUrl = rv.url
|
||||||
this.layout = false
|
this.layout = false
|
||||||
this.loadingShow = false
|
this.loadingShow = false
|
||||||
@@ -1062,12 +1062,27 @@ export default defineComponent({
|
|||||||
// height: 100%;
|
// height: 100%;
|
||||||
// }
|
// }
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center;
|
|
||||||
background-size: cover;
|
|
||||||
&.active{
|
&.active{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
img{
|
||||||
|
// object-fit: cover;
|
||||||
|
// width: 100%;
|
||||||
|
// height: 100%;
|
||||||
|
pointer-events: none;
|
||||||
|
float: left;
|
||||||
|
user-select:none;
|
||||||
|
-webkit-user-drag: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%,-50%) scale(1);
|
||||||
|
}
|
||||||
|
::selection {
|
||||||
|
// background: rgba(0,0,0,0);
|
||||||
|
// background: yellow;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.wh1{
|
.wh1{
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
|||||||
<!-- <div class="icon" @click="toGmailLogin"> -->
|
<!-- <div class="icon" @click="toGmailLogin"> -->
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<img src="@/assets/images/loginPage/gmailIcon.svg" alt="">
|
<img src="@/assets/images/loginPage/gmailIcon.svg" alt="">
|
||||||
<span>{{ displayText }}</span>
|
<span>{{ $props.text }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
props: {
|
props: {
|
||||||
text: {
|
text: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: 'Sign in with Google'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
@@ -108,9 +108,6 @@
|
|||||||
const toGmailLogin = ()=>{
|
const toGmailLogin = ()=>{
|
||||||
message.info(t('account.canNotUtilize'))
|
message.info(t('account.canNotUtilize'))
|
||||||
}
|
}
|
||||||
const displayText = computed(() => {
|
|
||||||
return props.text || t('Login.LoginWithGoogle')
|
|
||||||
})
|
|
||||||
onBeforeUnmount(()=>{
|
onBeforeUnmount(()=>{
|
||||||
var existingScript = document.querySelector(`script[src="${data.scriptSrc}"]`);
|
var existingScript = document.querySelector(`script[src="${data.scriptSrc}"]`);
|
||||||
if(existingScript){
|
if(existingScript){
|
||||||
@@ -123,7 +120,6 @@
|
|||||||
})
|
})
|
||||||
return {
|
return {
|
||||||
toGmailLogin,
|
toGmailLogin,
|
||||||
displayText,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -553,14 +553,13 @@ export default defineComponent({
|
|||||||
loginType: "EMAIL",
|
loginType: "EMAIL",
|
||||||
userId: this.userId,
|
userId: this.userId,
|
||||||
};
|
};
|
||||||
this.store.commit('set_loading', true)
|
this.$emit('update:isMask',true)
|
||||||
Https.axiosPost(Https.httpUrls.accountLogin, data)
|
Https.axiosPost(Https.httpUrls.accountLogin, data)
|
||||||
.then((rv: any) => {
|
.then((rv: any) => {
|
||||||
this.setSuccessLogin(rv);
|
this.setSuccessLogin(rv);
|
||||||
this.store.commit('set_loading', false)
|
|
||||||
})
|
})
|
||||||
.catch((res) => {
|
.catch((res) => {
|
||||||
this.store.commit('set_loading', false)
|
this.$emit('update:isMask',false)
|
||||||
});
|
});
|
||||||
},1000)
|
},1000)
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="Container">
|
<div class="Container">
|
||||||
<div class="icon" @click="openWeiXinModel">
|
<div class="icon" @click="openWeiXinModel">
|
||||||
<img src="@/assets/images/loginPage/weiXinIcon.svg" alt="" />
|
<img src="@/assets/images/loginPage/weiXinIcon.svg" alt="" />
|
||||||
<span>{{ displayText }}</span>
|
<span>{{ $props.text }}</span>
|
||||||
</div>
|
</div>
|
||||||
<weiXinModel ref="weiXinModel"></weiXinModel>
|
<weiXinModel ref="weiXinModel"></weiXinModel>
|
||||||
</div>
|
</div>
|
||||||
@@ -18,7 +18,6 @@ import {
|
|||||||
toRefs,
|
toRefs,
|
||||||
} from "vue";
|
} from "vue";
|
||||||
import weiXinModel from "./weiXinModel.vue";
|
import weiXinModel from "./weiXinModel.vue";
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "login",
|
name: "login",
|
||||||
components: {
|
components: {
|
||||||
@@ -27,25 +26,20 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
text: {
|
text: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: "Sign in with Wechat",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup() {
|
||||||
let weiXinDom = reactive({
|
let weiXinDom = reactive({
|
||||||
weiXinModel: null,
|
weiXinModel: null,
|
||||||
});
|
});
|
||||||
const { t } = useI18n()
|
|
||||||
const openWeiXinModel = () => {
|
const openWeiXinModel = () => {
|
||||||
weiXinDom.weiXinModel.init();
|
weiXinDom.weiXinModel.init();
|
||||||
};
|
};
|
||||||
const displayText = computed(() => {
|
|
||||||
return props.text || t('Login.LoginWithWechat')
|
|
||||||
})
|
|
||||||
onMounted(() => {});
|
onMounted(() => {});
|
||||||
return {
|
return {
|
||||||
...toRefs(weiXinDom),
|
...toRefs(weiXinDom),
|
||||||
openWeiXinModel,
|
openWeiXinModel,
|
||||||
displayText,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -458,7 +458,6 @@ export default defineComponent({
|
|||||||
message.info(t('newScaleImage.jsContent2'))
|
message.info(t('newScaleImage.jsContent2'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
store.state.Workspace.cachedRoutes = [];
|
|
||||||
let id = await getWorks(imgData.scaleImageData.id)
|
let id = await getWorks(imgData.scaleImageData.id)
|
||||||
await router.push(`/home/history/${id}`)
|
await router.push(`/home/history/${id}`)
|
||||||
store.commit('setChooseIsDesign',false)
|
store.commit('setChooseIsDesign',false)
|
||||||
|
|||||||
@@ -132,8 +132,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal_img_max">
|
<div class="modal_img_max">
|
||||||
<div v-if="!modalImg[0]?.id" class="modal_img" id="modal_img" :class="{active:flex_direction}">
|
<div v-if="!modalImg[0]?.id" class="modal_img" id="modal_img" :class="{active:flex_direction}">
|
||||||
<!-- <div class="modal_img" id="modal_img" :class="{active:flex_direction}"> -->
|
<div v-for="item,index in layoutList" :class="[moodb_className[index]]" class="modal_imgItem">
|
||||||
<div v-for="item,index in layoutList" :class="[moodb_className[index]]" :style="{'background-image':`url(${item.imgUrl})`}" class="modal_imgItem">
|
<img :src="item.imgUrl" v-modelImg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="modal_img">
|
<div v-else class="modal_img">
|
||||||
@@ -244,6 +244,30 @@ export default defineComponent({
|
|||||||
this.token = getCookie("token") || "";
|
this.token = getCookie("token") || "";
|
||||||
this.uploadUrl = getUploadUrl();
|
this.uploadUrl = getUploadUrl();
|
||||||
},
|
},
|
||||||
|
directives:{
|
||||||
|
modelImg:{
|
||||||
|
mounted(el) {
|
||||||
|
let parentNode = el.parentNode
|
||||||
|
if(parentNode.offsetHeight >= parentNode.offsetWidth){
|
||||||
|
el.style.height = 100+'%'
|
||||||
|
el.style.width = 'auto'
|
||||||
|
}else{
|
||||||
|
el.style.width = 100+'%'
|
||||||
|
el.style.height = 'auto'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updated (el) {
|
||||||
|
let parentNode = el.parentNode
|
||||||
|
if(parentNode.offsetHeight >= parentNode.offsetWidth){
|
||||||
|
el.style.height = 100+'%'
|
||||||
|
el.style.width = 'auto'
|
||||||
|
}else{
|
||||||
|
el.style.width = 100+'%'
|
||||||
|
el.style.height = 'auto'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
open(num: Number) {
|
open(num: Number) {
|
||||||
this.openClick = num;
|
this.openClick = num;
|
||||||
@@ -421,7 +445,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.edieShow = true
|
this.edieShow = true
|
||||||
if(this.moodb_[arr.length-1].length == 1){
|
if(this.moodb_[arr.length-1].length == 2){
|
||||||
this.moodb_className = this.moodb_[arr.length-1][0]
|
this.moodb_className = this.moodb_[arr.length-1][0]
|
||||||
}else{
|
}else{
|
||||||
this.moodb_className = this.moodb_[arr.length-1][random]
|
this.moodb_className = this.moodb_[arr.length-1][random]
|
||||||
@@ -604,7 +628,6 @@ export default defineComponent({
|
|||||||
height: calc(5rem*1.2);
|
height: calc(5rem*1.2);
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
&.modal_img::-webkit-scrollbar {
|
&.modal_img::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@@ -683,9 +706,15 @@ export default defineComponent({
|
|||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-repeat: no-repeat;
|
img{
|
||||||
background-position: center;
|
position: absolute;
|
||||||
background-size: cover;
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%,-50%);
|
||||||
|
// float: left;
|
||||||
|
// user-select:none;
|
||||||
|
// -webkit-user-drag: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.wh1{
|
.wh1{
|
||||||
width: 23%;
|
width: 23%;
|
||||||
|
|||||||
@@ -242,16 +242,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="prompt-input-container" v-show="!showMotion">
|
<div class="prompt-input-container" v-show="!showMotion">
|
||||||
<div class="title">
|
<div class="title">{{ $t('ProductImg.Prompt') }}</div>
|
||||||
<span>{{ $t('ProductImg.Prompt') }}</span>
|
|
||||||
<SvgIcon
|
|
||||||
class="cursor-icon"
|
|
||||||
@click="handleNavigateHelp"
|
|
||||||
name="CHelpFlip"
|
|
||||||
size="18"
|
|
||||||
color="#000"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<promptInput :content="prompt" ref="promptInputRef" />
|
<promptInput :content="prompt" ref="promptInputRef" />
|
||||||
</div>
|
</div>
|
||||||
<div class="transferPose" v-show="showMotion">
|
<div class="transferPose" v-show="showMotion">
|
||||||
@@ -389,7 +380,7 @@
|
|||||||
<a-spin size="large" />
|
<a-spin size="large" />
|
||||||
</div>
|
</div>
|
||||||
<template>
|
<template>
|
||||||
<Prompt v-if="scaleImageList[scaleImageIndex]?.resultType === 'ToProductImage'" v-model:showModal="showPromptAssist" />
|
<Prompt v-if="scaleImageList[scaleImageIndex]?.resultType === 'ToProductImage'" v-model:showModal="showPromptAssist" isDesignPage />
|
||||||
<PromptEditProduct v-if="scaleImageList[scaleImageIndex]?.resultType === 'Relight'" v-model:showModal="showPromptAssist" />
|
<PromptEditProduct v-if="scaleImageList[scaleImageIndex]?.resultType === 'Relight'" v-model:showModal="showPromptAssist" />
|
||||||
</template>
|
</template>
|
||||||
<Product
|
<Product
|
||||||
@@ -459,7 +450,7 @@ export default defineComponent({
|
|||||||
let userDetail: any = computed(() => {
|
let userDetail: any = computed(() => {
|
||||||
return store.state.UserHabit.userDetail
|
return store.state.UserHabit.userDetail
|
||||||
})
|
})
|
||||||
let { t, locale } = useI18n()
|
let { t } = useI18n()
|
||||||
const textareaRef = useTemplateRef<HTMLTextAreaElement>('textareaRef')
|
const textareaRef = useTemplateRef<HTMLTextAreaElement>('textareaRef')
|
||||||
const videoType = ref(2)
|
const videoType = ref(2)
|
||||||
const showMotion = computed(() => videoType.value === 1)
|
const showMotion = computed(() => videoType.value === 1)
|
||||||
@@ -608,13 +599,13 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
const showPromptAssist = ref(false)
|
const showPromptAssist = ref(false)
|
||||||
const handleClickAssistBtn = () => {
|
const handleClickAssistBtn = () => {
|
||||||
// const { httpType } = store.state.Workspace.probjects
|
const { httpType } = store.state.Workspace.probjects
|
||||||
// const isSingleDesign = httpType === 'SINGLE_DESIGN'
|
const isSingleDesign = httpType === 'SINGLE_DESIGN'
|
||||||
// if (!isSingleDesign) {
|
if (!isSingleDesign) {
|
||||||
// const promptText = t('ProductImg.Series')
|
const promptText = t('ProductImg.Series')
|
||||||
// productimg.productimgSearchName = promptText
|
productimg.productimgSearchName = promptText
|
||||||
// return
|
return
|
||||||
// }
|
}
|
||||||
showPromptAssist.value = true
|
showPromptAssist.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1319,13 +1310,7 @@ export default defineComponent({
|
|||||||
return videoType.value === 3 ? false : true
|
return videoType.value === 3 ? false : true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const handleNavigateHelp = () => {
|
|
||||||
const url =
|
|
||||||
locale === 'CHINESE_SIMPLIFIED'
|
|
||||||
? 'https://aida-user-manual-chinese.super.site/2b08f755cedd80a985cffdf2af80c538'
|
|
||||||
: 'https://aida-user-manual.super.site/advanced-tool/animated-product-image/to-product-video-prompt-assist '
|
|
||||||
window.open(url,'_blank')
|
|
||||||
}
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
clearInterval(prductimgTime)
|
clearInterval(prductimgTime)
|
||||||
clearInterval(remPrductimgTime)
|
clearInterval(remPrductimgTime)
|
||||||
@@ -1389,8 +1374,7 @@ export default defineComponent({
|
|||||||
handlePlayNewVideo,
|
handlePlayNewVideo,
|
||||||
isNewVideoPlaying,
|
isNewVideoPlaying,
|
||||||
showDropdown,
|
showDropdown,
|
||||||
inputPlaceholder,
|
inputPlaceholder
|
||||||
handleNavigateHelp
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@@ -1802,16 +1786,12 @@ export default defineComponent({
|
|||||||
:deep(.promptInput) {
|
:deep(.promptInput) {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.title {
|
.title {
|
||||||
display: flex;
|
font-weight: 500;
|
||||||
align-items: center;
|
color: #000;
|
||||||
column-gap: 1rem;
|
font-size: 1.7rem;
|
||||||
.cursor-icon {
|
margin-bottom: 1.4rem;
|
||||||
display: flex;
|
}
|
||||||
width: auto;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.prompt-container {
|
.prompt-container {
|
||||||
margin-top: 4rem;
|
margin-top: 4rem;
|
||||||
|
|||||||
@@ -55,16 +55,13 @@ export default defineComponent({
|
|||||||
const data = reactive({
|
const data = reactive({
|
||||||
openType:'',
|
openType:'',
|
||||||
componentKey:null,
|
componentKey:null,
|
||||||
isShowMark:true,
|
isShowMark:false,
|
||||||
routeQuery:{} as any,
|
routeQuery:{} as any,
|
||||||
selectObject:computed(()=>store.state.Workspace.probjects) as any,//选择的项目
|
selectObject:computed(()=>store.state.Workspace.probjects) as any,//选择的项目
|
||||||
chatData:null as any,
|
chatData:null as any,
|
||||||
dataLoad:true as any,
|
dataLoad:true as any,
|
||||||
cachedRoutes:computed(()=>store.state.Workspace.cachedRoutes),//
|
cachedRoutes:computed(()=>store.state.Workspace.cachedRoutes),//
|
||||||
})
|
})
|
||||||
onMounted(()=>{
|
|
||||||
data.isShowMark = false
|
|
||||||
})
|
|
||||||
let settingGetHistory:any = inject('settingGetHistory')
|
let settingGetHistory:any = inject('settingGetHistory')
|
||||||
const setIsShowMark = (boolean:boolean)=>{
|
const setIsShowMark = (boolean:boolean)=>{
|
||||||
data.isShowMark = boolean
|
data.isShowMark = boolean
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ const promptList = computed(() => {
|
|||||||
return [t('ProductImg.UploadWithoutModel'), t('ProductImg.UploadWithModel')]
|
return [t('ProductImg.UploadWithoutModel'), t('ProductImg.UploadWithModel')]
|
||||||
} else {
|
} else {
|
||||||
// 如果是从design来的
|
// 如果是从design来的
|
||||||
if (props.isDesignPage) {
|
if (isSingleDesign) {
|
||||||
// SINGLE_DESIGN: 两个提示词
|
// SINGLE_DESIGN: 两个提示词
|
||||||
// 根据年龄和性别选择对应的提示词
|
// 根据年龄和性别选择对应的提示词
|
||||||
let firstPrompt: string // 不带模特的提示词
|
let firstPrompt: string // 不带模特的提示词
|
||||||
@@ -255,8 +255,8 @@ const exampleList = computed(() => {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const { ageGroup, httpType, sex } = store.state.Workspace.probjects
|
const { ageGroup, httpType, sex } = store.state.Workspace.probjects
|
||||||
// const isSingleDesign = httpType === 'SINGLE_DESIGN'
|
const isSingleDesign = httpType === 'SINGLE_DESIGN'
|
||||||
// if (!isSingleDesign) return {}
|
if (!isSingleDesign) return {}
|
||||||
const isAdult = ageGroup === 'Adult'
|
const isAdult = ageGroup === 'Adult'
|
||||||
const isFemale = sex === 'Female'
|
const isFemale = sex === 'Female'
|
||||||
if (isAdult) {
|
if (isAdult) {
|
||||||
|
|||||||
@@ -1101,13 +1101,13 @@ export default defineComponent({
|
|||||||
|
|
||||||
const showPromptAssist = ref(false)
|
const showPromptAssist = ref(false)
|
||||||
const handleClickAssistBtn = () => {
|
const handleClickAssistBtn = () => {
|
||||||
// const { httpType } = store.state.Workspace.probjects
|
const { httpType } = store.state.Workspace.probjects
|
||||||
// const isSingleDesign = httpType === 'SINGLE_DESIGN'
|
const isSingleDesign = httpType === 'SINGLE_DESIGN'
|
||||||
// if (props.isDesignPage && !isSingleDesign) {
|
if (props.isDesignPage && !isSingleDesign) {
|
||||||
// const promptText = t('ProductImg.Series')
|
const promptText = t('ProductImg.Series')
|
||||||
// productImgData.searchName[props.productimgMenu.value] = promptText
|
productImgData.searchName[props.productimgMenu.value] = promptText
|
||||||
// return
|
return
|
||||||
// }
|
}
|
||||||
showPromptAssist.value = true
|
showPromptAssist.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
<ul
|
<ul
|
||||||
class="product_detail"
|
class="product_detail"
|
||||||
:class="[
|
:class="[
|
||||||
{ academic: item.type == 'academic' },
|
{ academic: item.type == 'academic' && !isSelectSuccessively },
|
||||||
{ chinese: isSelectSuccessively }
|
{ chinese: isSelectSuccessively }
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
@@ -106,12 +106,12 @@ export default defineComponent({
|
|||||||
Yearly: '年度',
|
Yearly: '年度',
|
||||||
monthly: [
|
monthly: [
|
||||||
{
|
{
|
||||||
title: '使用版',
|
title: '免费版',
|
||||||
img: CChargeIcon,
|
img: CChargeIcon,
|
||||||
type: 'personal',
|
type: 'personal',
|
||||||
info: '您的AI时尚设计助手',
|
info: '您的AI时尚设计助手',
|
||||||
price: 'HK$0',
|
price: 'HK$0',
|
||||||
detail: '自注册之日起 5 天内 · 50 个积分',
|
detail: '5天·50积分',
|
||||||
highlight: '',
|
highlight: '',
|
||||||
discounts: '9折优惠',
|
discounts: '9折优惠',
|
||||||
detailList: [
|
detailList: [
|
||||||
@@ -185,12 +185,12 @@ export default defineComponent({
|
|||||||
],
|
],
|
||||||
yearl: [
|
yearl: [
|
||||||
{
|
{
|
||||||
title: '试用版',
|
title: '免费版',
|
||||||
img: CChargeIcon,
|
img: CChargeIcon,
|
||||||
type: 'personal',
|
type: 'personal',
|
||||||
info: '您的AI时尚设计助手',
|
info: '您的AI时尚设计助手',
|
||||||
price: 'HK$0',
|
price: 'HK$0',
|
||||||
detail: '自注册之日起 5 天内 · 50 个积分',
|
detail: '5天·50积分',
|
||||||
highlight: '',
|
highlight: '',
|
||||||
discounts: '9折优惠',
|
discounts: '9折优惠',
|
||||||
detailList: [
|
detailList: [
|
||||||
@@ -250,12 +250,12 @@ export default defineComponent({
|
|||||||
Yearly: 'Yearly',
|
Yearly: 'Yearly',
|
||||||
monthly: [
|
monthly: [
|
||||||
{
|
{
|
||||||
title: 'Trial',
|
title: 'Free',
|
||||||
img: CChargeIcon,
|
img: CChargeIcon,
|
||||||
type: 'personal',
|
type: 'personal',
|
||||||
info: 'Your AI Fashion Design Assistant',
|
info: 'Your AI Fashion Design Assistant',
|
||||||
price: 'HK$0',
|
price: 'HK$0',
|
||||||
detail: '5 days from sign-up · 50 credits',
|
detail: '5 days · 50 credits',
|
||||||
highlight: '',
|
highlight: '',
|
||||||
discounts: '10% off',
|
discounts: '10% off',
|
||||||
detailList: [
|
detailList: [
|
||||||
@@ -329,12 +329,12 @@ export default defineComponent({
|
|||||||
],
|
],
|
||||||
yearl: [
|
yearl: [
|
||||||
{
|
{
|
||||||
title: 'Trial',
|
title: 'Free',
|
||||||
img: CChargeIcon,
|
img: CChargeIcon,
|
||||||
type: 'personal',
|
type: 'free',
|
||||||
info: 'Your AI Fashion Design Assistant',
|
info: 'Your AI Fashion Design Assistant',
|
||||||
price: 'HK$0',
|
price: 'HK$0',
|
||||||
detail: '5 days from sign-up · 50 credits',
|
detail: '5 days · 50 credits',
|
||||||
highlight: '',
|
highlight: '',
|
||||||
discounts: '10% off',
|
discounts: '10% off',
|
||||||
detailList: [
|
detailList: [
|
||||||
|
|||||||
@@ -1543,13 +1543,11 @@ export default {
|
|||||||
LoginMethod: '使用以下方式登录:',
|
LoginMethod: '使用以下方式登录:',
|
||||||
Individual: '个人账号',
|
Individual: '个人账号',
|
||||||
Academic: '学术账号',
|
Academic: '学术账号',
|
||||||
LogonToAiDA: '登录到AiDA 3.1',
|
LogoOnToAiDA: '登录到AiDA 3.1',
|
||||||
Infomation: '请填写以下信息',
|
Infomation: '请填写以下信息',
|
||||||
Device: '请使用iPad或电脑登录',
|
Device: '请使用iPad或电脑登录',
|
||||||
AgreePolicies: '请勾选条款、隐私政策和费用',
|
AgreePolicies: '请勾选条款、隐私政策和费用',
|
||||||
PasswordConditions: '您必须满足所有密码条件才能注册',
|
PasswordConditions: '您必须满足所有密码条件才能注册'
|
||||||
LoginWithGoogle: '使用谷歌账号登录',
|
|
||||||
LoginWithWechat: '使用微信登录',
|
|
||||||
},
|
},
|
||||||
LoginPersonal: {
|
LoginPersonal: {
|
||||||
Email: '邮箱',
|
Email: '邮箱',
|
||||||
|
|||||||
@@ -959,7 +959,7 @@ export default {
|
|||||||
MOSTPOPULAR: 'MOST POPULAR',
|
MOSTPOPULAR: 'MOST POPULAR',
|
||||||
Monthly: 'Monthly',
|
Monthly: 'Monthly',
|
||||||
Yearly: 'Yearly',
|
Yearly: 'Yearly',
|
||||||
promotionCode: 'Coupon Code',
|
promotionCode: 'Coupon',
|
||||||
use: 'Apply',
|
use: 'Apply',
|
||||||
PromoCodeError:
|
PromoCodeError:
|
||||||
'Please check if the promo code is correct or if the date has expired',
|
'Please check if the promo code is correct or if the date has expired',
|
||||||
@@ -1591,9 +1591,7 @@ export default {
|
|||||||
Infomation: 'Please fill your information below',
|
Infomation: 'Please fill your information below',
|
||||||
Device: 'If you need to design, please log in using an iPad or computer.',
|
Device: 'If you need to design, please log in using an iPad or computer.',
|
||||||
AgreePolicies: 'Please agree to all terms, privacy policy, and fees.',
|
AgreePolicies: 'Please agree to all terms, privacy policy, and fees.',
|
||||||
PasswordConditions: 'You must satisfy ALL password conditions to register.',
|
PasswordConditions: 'You must satisfy ALL password conditions to register.'
|
||||||
LoginWithGoogle: 'Sign in with Google',
|
|
||||||
LoginWithWechat: 'Sign in with Wechat',
|
|
||||||
},
|
},
|
||||||
LoginPersonal: {
|
LoginPersonal: {
|
||||||
Email: 'Email',
|
Email: 'Email',
|
||||||
|
|||||||
@@ -290,13 +290,6 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
component: () =>
|
component: () =>
|
||||||
import("@/component/Administrator/organization/organization.vue"),
|
import("@/component/Administrator/organization/organization.vue"),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: "subscriptionPlan",
|
|
||||||
name: "subscriptionPlan",
|
|
||||||
meta: { enter: 3 },
|
|
||||||
component: () =>
|
|
||||||
import("@/component/Administrator/subscriptionPlan.vue"),
|
|
||||||
},
|
|
||||||
//企业版教育管理员页面
|
//企业版教育管理员页面
|
||||||
{
|
{
|
||||||
path: "allUserSE",
|
path: "allUserSE",
|
||||||
@@ -505,7 +498,6 @@ function isTimeRangePassed(timeRange) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
router.beforeEach((to: any, from, next) => {
|
router.beforeEach((to: any, from, next) => {
|
||||||
store.commit("set_view_loading", true);
|
|
||||||
//系统维护时间
|
//系统维护时间
|
||||||
const time = '2025-11-21T23:00:00 - 2025-11-22T00:00:00';
|
const time = '2025-11-21T23:00:00 - 2025-11-22T00:00:00';
|
||||||
if (isTimeRangePassed(time) == 'in_progress') {
|
if (isTimeRangePassed(time) == 'in_progress') {
|
||||||
@@ -548,7 +540,5 @@ router.beforeEach((to: any, from, next) => {
|
|||||||
|
|
||||||
// if(systemUser == 0){//游客用户只能进入这两个页面
|
// if(systemUser == 0){//游客用户只能进入这两个页面
|
||||||
});
|
});
|
||||||
router.afterEach((to, from) => {
|
|
||||||
store.commit("set_view_loading", false);
|
|
||||||
});
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
@@ -13,18 +13,10 @@ export interface RootState{
|
|||||||
|
|
||||||
export default createStore<RootState>({
|
export default createStore<RootState>({
|
||||||
state: {
|
state: {
|
||||||
loading: false,
|
|
||||||
view_loading: false,
|
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
set_loading(state, v){
|
|
||||||
state.loading = v;
|
|
||||||
},
|
|
||||||
set_view_loading(state, v){
|
|
||||||
state.view_loading = v;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -177,12 +177,6 @@ const all = (t)=>{
|
|||||||
route:'/administrator/organization',
|
route:'/administrator/organization',
|
||||||
key:'sub13',
|
key:'sub13',
|
||||||
isShow:true,
|
isShow:true,
|
||||||
},{
|
|
||||||
name:'Subscription Plan',
|
|
||||||
icon:'usetime',
|
|
||||||
route:'/administrator/subscriptionPlan',
|
|
||||||
key:'sub14',
|
|
||||||
isShow:true,
|
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
const schoolOrEnterprise = (t) =>{
|
const schoolOrEnterprise = (t) =>{
|
||||||
|
|||||||
@@ -325,11 +325,6 @@ export const Https = {
|
|||||||
deletePromCode:`/api/stripe/deletePromCode`,//删除优惠券
|
deletePromCode:`/api/stripe/deletePromCode`,//删除优惠券
|
||||||
addOrganization:`/api/inquiry/addOrganization`,//添加企业版或者教育版
|
addOrganization:`/api/inquiry/addOrganization`,//添加企业版或者教育版
|
||||||
queryOrganization:`/api/inquiry/queryOrganization`,//查询企业版或者教育版
|
queryOrganization:`/api/inquiry/queryOrganization`,//查询企业版或者教育版
|
||||||
createSubscribePlan:'/api/subscription_plan/createPlan', // 创建订阅计划
|
|
||||||
deleteSubscribePlan: '/api/subscription_plan/deletePlan', // 删除订阅计划
|
|
||||||
updateSubscribePlan: '/api/subscription_plan/updatePlan', // 修改订阅计划
|
|
||||||
searchAllSubscribePlan: '/api/subscription_plan/searchByPage', // 查询所有订阅计划
|
|
||||||
switchSubscribePlan:'/api/subscription_plan/switchSubscriptionPlan', // 切换订阅计划
|
|
||||||
|
|
||||||
|
|
||||||
//云生成
|
//云生成
|
||||||
|
|||||||
@@ -427,12 +427,11 @@
|
|||||||
<div class="userSystem" v-show="pastDuePage">
|
<div class="userSystem" v-show="pastDuePage">
|
||||||
{{ $t('Header.pastDue') }}
|
{{ $t('Header.pastDue') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="router" v-if="!loading">
|
<div class="router" v-if="!getLangIsShowMark">
|
||||||
<home
|
<home
|
||||||
ref="home"
|
ref="home"
|
||||||
@setNewProject="() => (leftShow = true)"
|
@setNewProject="() => (leftShow = true)"
|
||||||
@setTask="setTask"
|
@setTask="setTask"
|
||||||
:key="userDetail.language"
|
|
||||||
></home>
|
></home>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -443,10 +442,10 @@
|
|||||||
<UpgradePlan ref="UpgradePlan"></UpgradePlan>
|
<UpgradePlan ref="UpgradePlan"></UpgradePlan>
|
||||||
<TaskPage ref="TaskPage"></TaskPage>
|
<TaskPage ref="TaskPage"></TaskPage>
|
||||||
|
|
||||||
<!-- <div class="mark_loading" v-show="loading">
|
<div class="mark_loading" v-show="getLangIsShowMark">
|
||||||
<a-spin size="large" />
|
<a-spin size="large" />
|
||||||
</div> -->
|
</div>
|
||||||
<!-- <RobotAssist v-if="!loading"></RobotAssist> -->
|
<!-- <RobotAssist v-if="!getLangIsShowMark"></RobotAssist> -->
|
||||||
<scaleVideo ref="scaleVideo"></scaleVideo>
|
<scaleVideo ref="scaleVideo"></scaleVideo>
|
||||||
<!-- 进行续订 -->
|
<!-- 进行续订 -->
|
||||||
<renew ref="renew"></renew>
|
<renew ref="renew"></renew>
|
||||||
@@ -657,7 +656,7 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
|
|
||||||
let activeCredits = ref(false)
|
let activeCredits = ref(false)
|
||||||
let loading = computed(() => (store.state.loading))
|
let getLangIsShowMark = ref(true)
|
||||||
let messageNum = computed(() => {
|
let messageNum = computed(() => {
|
||||||
return store.state.UserHabit.messageSystem.messageNum
|
return store.state.UserHabit.messageSystem.messageNum
|
||||||
})
|
})
|
||||||
@@ -1071,7 +1070,7 @@ export default defineComponent({
|
|||||||
isMurmur,
|
isMurmur,
|
||||||
credits,
|
credits,
|
||||||
activeCredits,
|
activeCredits,
|
||||||
loading,
|
getLangIsShowMark,
|
||||||
messageNum,
|
messageNum,
|
||||||
messageType,
|
messageType,
|
||||||
...toRefs(stateList),
|
...toRefs(stateList),
|
||||||
@@ -1129,11 +1128,11 @@ export default defineComponent({
|
|||||||
this.store
|
this.store
|
||||||
.dispatch('getLangType')
|
.dispatch('getLangType')
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.store.commit('set_loading', false)
|
this.getLangIsShowMark = false
|
||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.store.commit('set_loading', false)
|
this.getLangIsShowMark = false
|
||||||
reject()
|
reject()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1335,7 +1334,7 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
setLang(v) {
|
setLang(v) {
|
||||||
this.store.commit('set_loading', true)
|
this.getLangIsShowMark = true
|
||||||
Https.axiosGet(Https.httpUrls.changeUserLanguage, { params: { language: v } })
|
Https.axiosGet(Https.httpUrls.changeUserLanguage, { params: { language: v } })
|
||||||
.then(rv => {
|
.then(rv => {
|
||||||
if (rv) {
|
if (rv) {
|
||||||
@@ -1352,11 +1351,11 @@ export default defineComponent({
|
|||||||
window.location.reload()
|
window.location.reload()
|
||||||
// window.location.href = '/home';
|
// window.location.href = '/home';
|
||||||
}
|
}
|
||||||
this.store.commit('set_loading', false)
|
this.getLangIsShowMark = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.store.commit('set_loading', false)
|
this.getLangIsShowMark = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -43,12 +43,15 @@
|
|||||||
<span>{{ t('Login.LogonToAiDA') }}</span>
|
<span>{{ t('Login.LogonToAiDA') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="info" v-show="!loginType">{{ t('Login.Infomation') }}</div>
|
<div class="info" v-show="!loginType">{{ t('Login.Infomation') }}</div>
|
||||||
<personal ref="personal" v-if="loginType == 'personal'"></personal>
|
<personal ref="personal" v-if="loginType == 'personal'" v-model:isMask="isMask"></personal>
|
||||||
<school ref="school" v-if="loginType == 'school'"></school>
|
<school ref="school" v-if="loginType == 'school'"></school>
|
||||||
<enterprise ref="enterprise" v-if="loginType == 'enterprise'"></enterprise>
|
<enterprise ref="enterprise" v-if="loginType == 'enterprise'"></enterprise>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mark_loading" v-show="isMask">
|
||||||
|
<a-spin size="large" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -100,6 +103,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
const loginData = reactive({
|
const loginData = reactive({
|
||||||
loginType: "",
|
loginType: "",
|
||||||
|
isMask: false,
|
||||||
});
|
});
|
||||||
const dataDom = reactive({
|
const dataDom = reactive({
|
||||||
personal: null as any,
|
personal: null as any,
|
||||||
|
|||||||
Reference in New Issue
Block a user