From ea7fa29b60723fe2aa0f38373aaf281a535db1d3 Mon Sep 17 00:00:00 2001 From: yangxiaohu Date: Tue, 29 Jul 2025 12:31:09 +0800 Subject: [PATCH 01/11] feat: frontier home page for onchain --- src/apis/frontiter.api.ts | 6 ++++++ src/assets/home/badge.svg | 3 +++ src/assets/home/dollar-circle.svg | 3 +++ src/assets/home/hourglass.svg | 3 +++ src/components/home/frontiers.tsx | 32 +++++++++++++++++++++++++------ 5 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 src/assets/home/badge.svg create mode 100644 src/assets/home/dollar-circle.svg create mode 100644 src/assets/home/hourglass.svg diff --git a/src/apis/frontiter.api.ts b/src/apis/frontiter.api.ts index a4b014b5..4b4da0cf 100644 --- a/src/apis/frontiter.api.ts +++ b/src/apis/frontiter.api.ts @@ -45,6 +45,12 @@ export interface FrontierListItem { reputation_permission: number status: string title: string + // start + total_asset_amount: number + reward_asset_type: string + min_ranking_grade: string + days_left: number + // end template_ext?: { template_id: string gif_resource?: string diff --git a/src/assets/home/badge.svg b/src/assets/home/badge.svg new file mode 100644 index 00000000..5435e5ed --- /dev/null +++ b/src/assets/home/badge.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/home/dollar-circle.svg b/src/assets/home/dollar-circle.svg new file mode 100644 index 00000000..afe7f5fc --- /dev/null +++ b/src/assets/home/dollar-circle.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/home/hourglass.svg b/src/assets/home/hourglass.svg new file mode 100644 index 00000000..21922142 --- /dev/null +++ b/src/assets/home/hourglass.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/home/frontiers.tsx b/src/components/home/frontiers.tsx index 8aecbb3c..7548d5b4 100644 --- a/src/components/home/frontiers.tsx +++ b/src/components/home/frontiers.tsx @@ -1,9 +1,14 @@ -import arrowRight from '@/assets/icons/arrow-right.svg' +import { message, Spin } from 'antd' import { useNavigate } from 'react-router-dom' import { useEffect, useMemo, useState } from 'react' + +import arrowRight from '@/assets/icons/arrow-right.svg' +import badgeIcon from '@/assets/home/badge.svg' +import DollarCircle from '@/assets/home/dollar-circle.svg?react' +import Hourglass from '@/assets/home/hourglass.svg?react' + import { FrontierListItem } from '@/apis/frontiter.api' import { frontierStoreActions, useFrontierStore } from '@/stores/frontier.store' -import { message, Spin } from 'antd' const Frontiers = () => { const navigate = useNavigate() @@ -54,7 +59,7 @@ const Frontiers = () => { {displayFrontiers.map((item) => (
handleFrontierClick(item)} > { background: 'linear-gradient(180deg, rgba(0, 0, 0, 0) 21.88%, #000000 100%)' }} > +
+ {item.min_ranking_grade || 'S'} +

{item.title}

{item.description.frontier_desc}
-
- Start - +
+
+ + {item.total_asset_amount || 2000} + {item.reward_asset_type || 'XNY'} + + {item.days_left || 10}D +
+
+ Start + +
From cda20bcae76e6125cf7b199bf45ba72b387139da Mon Sep 17 00:00:00 2001 From: yangxiaohu Date: Tue, 29 Jul 2025 18:56:24 +0800 Subject: [PATCH 02/11] feat: frontier activity info for onchain --- src/apis/frontiter.api.ts | 28 +++++++++++- src/components/frontier/crypto/upload.tsx | 8 +--- src/components/home/activity-info.tsx | 56 +++++++++++++++++++++++ src/components/home/frontiers.tsx | 2 +- src/stores/frontier.store.ts | 21 ++++++++- src/views/frontiers/home.tsx | 3 ++ 6 files changed, 108 insertions(+), 10 deletions(-) create mode 100644 src/components/home/activity-info.tsx diff --git a/src/apis/frontiter.api.ts b/src/apis/frontiter.api.ts index 4b4da0cf..dc56a311 100644 --- a/src/apis/frontiter.api.ts +++ b/src/apis/frontiter.api.ts @@ -1,5 +1,6 @@ import { AxiosInstance } from 'axios' import request, { PaginationResponse, TPagination } from './request' +import { data } from 'react-router-dom' interface Response { data: T @@ -15,6 +16,22 @@ export interface TaskRewardInfo { reward_value: number } +export type ActiveStatus = 'ACTIVE' | 'INACTIVE' | 'COMPLETED' +export interface FrontierActivityInfoItem { + activity_id: string + start_time: string + end_time: string + reward_mode: 'EQUAL_SPLIT_ON_END' | 'FIRST_COME_FIRST_SERVE' + min_ranking_grade: string + total_asset_amount: number + max_reward_count: number + reward_asset_type: string + participants: number + submissions: number + status: ActiveStatus + rules?: string[] +} + export interface TaskDetail { frontier_id: string task_id: string @@ -31,6 +48,7 @@ export interface TaskDetail { question_status?: number // 1: available, 2: no more questions, 3. need to change question group data_requirements: unknown reward_info: readonly TaskRewardInfo[] + status: 'PENDING' | 'SUBMITTED' | 'REFUSED' | 'ADOPT' txHashUrl: string } @@ -163,7 +181,15 @@ class frontier { } async getFrontiers(): Promise> { - const res = await this.request.post('/v2/frontier/list ') + const res = await this.request.post('/v2/frontier/list ', data) + return res.data + } + + async getFrontierActivityInfo(data: { + frontier_id: string + status?: ActiveStatus + }): Promise> { + const res = await this.request.post('/v2/frontier/activity/info', data) return res.data } diff --git a/src/components/frontier/crypto/upload.tsx b/src/components/frontier/crypto/upload.tsx index d73c5a52..9c9d6f5f 100644 --- a/src/components/frontier/crypto/upload.tsx +++ b/src/components/frontier/crypto/upload.tsx @@ -98,13 +98,7 @@ const Upload: React.FC = ({ value, onChange, error, description, is return (
- + {value.length === 0 ? ( isMobile ? ( diff --git a/src/components/home/activity-info.tsx b/src/components/home/activity-info.tsx new file mode 100644 index 00000000..d63afcbe --- /dev/null +++ b/src/components/home/activity-info.tsx @@ -0,0 +1,56 @@ +import { cn } from '@udecode/cn' +import { useParams } from 'react-router-dom' +import { useEffect, useState } from 'react' +import dayjs from 'dayjs' + +import frontierApi, { FrontierActivityInfoItem } from '@/apis/frontiter.api' + +export default function ActivityInfo({ className }: { className?: string }) { + const { frontier_id } = useParams() + const [activityInfoList, setActivityInfoList] = useState([]) + + async function getFrontierActivityInfo(frontier_id: string) { + const res = await frontierApi.getFrontierActivityInfo({ frontier_id }) + if (res.errorCode === 0) { + setActivityInfoList(res.data[0]) + console.log(res.data) + } + } + useEffect(() => { + if (!frontier_id) return + getFrontierActivityInfo(frontier_id) + }, [frontier_id]) + return ( +
    0 ? 'block' : 'hidden', className)}> + {activityInfoList.map((item) => ( +
  • +
    +
    +
    Duration
    +
    + {dayjs(item.start_time).format('YYYY-MM-DD')} to {dayjs(item.end_time).format('YYYY-MM-DD')} +
    +
    +
    +
    Min Quality
    +
    + {item.min_ranking_grade} +
    +
    +
    +
    Total Rewards
    +
    + {item.total_asset_amount} + {item.reward_asset_type} +
    +
    +
    +
    Total Submissions
    +
    {item.submissions}
    +
    +
    +
  • + ))} +
+ ) +} diff --git a/src/components/home/frontiers.tsx b/src/components/home/frontiers.tsx index 7548d5b4..27acfd1e 100644 --- a/src/components/home/frontiers.tsx +++ b/src/components/home/frontiers.tsx @@ -87,7 +87,7 @@ const Frontiers = () => {
{item.total_asset_amount || 2000} - {item.reward_asset_type || 'XNY'} + {item.reward_asset_type} {item.days_left || 10}D
diff --git a/src/stores/frontier.store.ts b/src/stores/frontier.store.ts index 33321e1e..19c5bc8e 100644 --- a/src/stores/frontier.store.ts +++ b/src/stores/frontier.store.ts @@ -1,10 +1,18 @@ -import frontierApi, { FrontierListItem, TaskDetail, SubmissionStatics, SubmissionRecord } from '@/apis/frontiter.api' +import frontierApi, { + FrontierListItem, + TaskDetail, + SubmissionStatics, + SubmissionRecord, + FrontierActivityListItem, + ActiveStatus +} from '@/apis/frontiter.api' import { debounce } from 'lodash' import { proxy, useSnapshot } from 'valtio' import { message } from 'antd' type FrontierStore = { frontierList: FrontierListItem[] + frontierActivities: FrontierActivityListItem[] pageData: { list: TaskDetail[] total: number @@ -31,6 +39,7 @@ type FrontierStore = { export const frontiersStore = proxy({ frontierList: [], + frontierActivities: [], pageData: { list: [], total: 0, @@ -134,6 +143,15 @@ async function getFrontierList() { return res.data } +async function getFrontierActivities(data: { frontier_id: string; status?: ActiveStatus }) { + const res = await frontierApi.getFrontierActivities({ + frontier_id: data.frontier_id, + status: data.status + }) + frontiersStore.frontierActivities = res.data || [] + return res.data +} + export function useFrontierStore() { return useSnapshot(frontiersStore) } @@ -166,6 +184,7 @@ export const getFrontierUserRecords = debounce(async (params: { page: number }) export const frontierStoreActions = { getFrontierList, + getFrontierActivities, changeFrontiersFilter, changeFrontiersHistoryFilter, getFrontierUserStatics, diff --git a/src/views/frontiers/home.tsx b/src/views/frontiers/home.tsx index 3edd5a39..c994e535 100644 --- a/src/views/frontiers/home.tsx +++ b/src/views/frontiers/home.tsx @@ -4,6 +4,8 @@ import { ArrowLeft } from 'lucide-react' import { useNavigate, useParams } from 'react-router-dom' import FrontierTaskList from '@/components/robotics/task-list' +import ActivityInfo from '@/components/home/activity-info' + import { useEffect, useState } from 'react' import frontierApi, { FrontierItemType, MediaName } from '@/apis/frontiter.api' import XIcon from '@/assets/robotics/x-logo.svg' @@ -69,6 +71,7 @@ export default function Component() {
{frontierInfo?.description}
+
From 2925481d23fe27e91f5d86c368e80b3709bc4dd1 Mon Sep 17 00:00:00 2001 From: yangxiaohu Date: Wed, 30 Jul 2025 12:19:58 +0800 Subject: [PATCH 03/11] feat: frontier home onchainshaow --- src/apis/frontiter.api.ts | 12 ++- src/components/home/activity-info.tsx | 135 ++++++++++++++++++++------ src/components/home/frontiers.tsx | 70 ++++++++----- src/stores/frontier.store.ts | 8 +- src/views/frontiers/home.tsx | 2 +- 5 files changed, 164 insertions(+), 63 deletions(-) diff --git a/src/apis/frontiter.api.ts b/src/apis/frontiter.api.ts index dc56a311..99dd8771 100644 --- a/src/apis/frontiter.api.ts +++ b/src/apis/frontiter.api.ts @@ -23,13 +23,14 @@ export interface FrontierActivityInfoItem { end_time: string reward_mode: 'EQUAL_SPLIT_ON_END' | 'FIRST_COME_FIRST_SERVE' min_ranking_grade: string + days_left: number total_asset_amount: number max_reward_count: number reward_asset_type: string participants: number submissions: number status: ActiveStatus - rules?: string[] + rules?: readonly string[] } export interface TaskDetail { @@ -63,11 +64,12 @@ export interface FrontierListItem { reputation_permission: number status: string title: string + activities: FrontierActivityInfoItem[] // start - total_asset_amount: number - reward_asset_type: string - min_ranking_grade: string - days_left: number + // total_asset_amount: number + // reward_asset_type: string + // min_ranking_grade: string + // days_left: number // end template_ext?: { template_id: string diff --git a/src/components/home/activity-info.tsx b/src/components/home/activity-info.tsx index d63afcbe..07c58b48 100644 --- a/src/components/home/activity-info.tsx +++ b/src/components/home/activity-info.tsx @@ -3,6 +3,9 @@ import { useParams } from 'react-router-dom' import { useEffect, useState } from 'react' import dayjs from 'dayjs' +import { ChevronUp } from 'lucide-react' + +import { formatNumber } from '@/utils/str' import frontierApi, { FrontierActivityInfoItem } from '@/apis/frontiter.api' export default function ActivityInfo({ className }: { className?: string }) { @@ -20,37 +23,113 @@ export default function ActivityInfo({ className }: { className?: string }) { if (!frontier_id) return getFrontierActivityInfo(frontier_id) }, [frontier_id]) + return ( -
    0 ? 'block' : 'hidden', className)}> - {activityInfoList.map((item) => ( -
  • -
    -
    -
    Duration
    -
    - {dayjs(item.start_time).format('YYYY-MM-DD')} to {dayjs(item.end_time).format('YYYY-MM-DD')} +
    0 ? 'block' : 'hidden', className)}> +
      + {activityInfoList.map((item) => ( +
    • +
      +
      +
      Duration
      +
      + {dayjs(item.start_time).format('YYYY-MM-DD')} to {dayjs(item.end_time).format('YYYY-MM-DD')} +
      -
    -
    -
    Min Quality
    -
    - {item.min_ranking_grade} +
    +
    Min Quality
    +
    + {item.min_ranking_grade} +
    -
    -
    -
    Total Rewards
    -
    - {item.total_asset_amount} - {item.reward_asset_type} +
    +
    Total Rewards
    +
    + {formatNumber(item.total_asset_amount || 0)} + {item.reward_asset_type} +
    -
    -
    -
    Total Submissions
    -
    {item.submissions}
    -
    -
    -
  • - ))} -
+ {item.reward_mode !== 'EQUAL_SPLIT_ON_END' ? ( +
+
Total Submissions
+
{formatNumber(item.submissions || 0)}
+
+ ) : ( +
+
Target
+
+ + + + + + + + + + + + + {formatNumber(item.submissions || 0)}/{formatNumber(item.max_reward_count || 0)} +
+
+ )} + + + + ))} + + + ) +} + +const defaultRules = [ + 'Multiple valid submissions count for reward sharing', + 'Minimum data quality requirement: Grade S', + 'Below standard submissions receive points reward', + 'Quality assessment based on accuracy and completeness', + 'First come, first served: Fixed rewards for reaching baseline score during activity period. Once required quantity is reached, no more rewards will be distributed even if activity continues.Below standard gets points reward', + 'Divide and share mode: Multiple submissions valid, each counts for sharing. Below standard gets points reward.' +] + +function Rules({ rules = defaultRules }: { rules?: string[] }) { + const [showRules, setShowRules] = useState(false) + + return ( +
+

+ 📋 Activity Rules{' '} + setShowRules(!showRules)} + /> +

+
    + {rules?.map((rule) =>
  • {rule}
  • )} +
+
) } diff --git a/src/components/home/frontiers.tsx b/src/components/home/frontiers.tsx index 27acfd1e..2355fe0c 100644 --- a/src/components/home/frontiers.tsx +++ b/src/components/home/frontiers.tsx @@ -17,11 +17,20 @@ const Frontiers = () => { const { frontierList } = useFrontierStore() const displayFrontiers = useMemo(() => { - return frontierList.filter((item) => { - return !['FOOD_TPL_000002', 'FOOD_TPL_000003', 'FOOD_TPL_000004', 'FOOD_TPL_000005'].includes( - item.template_ext?.template_id || '' - ) - }) + return frontierList + .filter((item) => { + return !['FOOD_TPL_000002', 'FOOD_TPL_000003', 'FOOD_TPL_000004', 'FOOD_TPL_000005'].includes( + item.template_ext?.template_id || '' + ) + }) + .map((item) => { + return { + ...item, + activities: item.activities?.filter((activity) => { + return activity.status === 'ACTIVE' + }) + } + }) }, [frontierList]) async function getFrontiers() { @@ -68,34 +77,45 @@ const Frontiers = () => { className="size-full object-cover transition-all group-hover:scale-[1.2]" />
-
- {item.min_ranking_grade || 'S'} -
-
+ {item.activities?.[0] && ( +
+ {item.activities?.[0].min_ranking_grade || 'S'} +
+ )} +

{item.title}

{item.description.frontier_desc}
-
-
- - {item.total_asset_amount || 2000} - {item.reward_asset_type} - - {item.days_left || 10}D + {item.activities?.[0] && ( +
+
+
+
+
+ + {item.activities?.[0].total_asset_amount || 0} + {item.activities?.[0].reward_asset_type} +
+
+ + {item.activities?.[0].days_left || 0}D +
+
+
+ Start + +
+
-
- Start - -
-
+ )}
))} diff --git a/src/stores/frontier.store.ts b/src/stores/frontier.store.ts index 19c5bc8e..2a29e661 100644 --- a/src/stores/frontier.store.ts +++ b/src/stores/frontier.store.ts @@ -3,7 +3,7 @@ import frontierApi, { TaskDetail, SubmissionStatics, SubmissionRecord, - FrontierActivityListItem, + FrontierActivityInfoItem, ActiveStatus } from '@/apis/frontiter.api' import { debounce } from 'lodash' @@ -12,7 +12,7 @@ import { message } from 'antd' type FrontierStore = { frontierList: FrontierListItem[] - frontierActivities: FrontierActivityListItem[] + frontierActivities: FrontierActivityInfoItem[] pageData: { list: TaskDetail[] total: number @@ -144,11 +144,11 @@ async function getFrontierList() { } async function getFrontierActivities(data: { frontier_id: string; status?: ActiveStatus }) { - const res = await frontierApi.getFrontierActivities({ + const res = await frontierApi.getFrontierActivityInfo({ frontier_id: data.frontier_id, status: data.status }) - frontiersStore.frontierActivities = res.data || [] + frontiersStore.frontierActivities = res.data[0] || [] return res.data } diff --git a/src/views/frontiers/home.tsx b/src/views/frontiers/home.tsx index c994e535..efd167b5 100644 --- a/src/views/frontiers/home.tsx +++ b/src/views/frontiers/home.tsx @@ -70,8 +70,8 @@ export default function Component() {
{frontierInfo?.description}
+ -
From e1fe10e42248ad0bd9a6e54267ce98cc188ed9cc Mon Sep 17 00:00:00 2001 From: yangxiaohu Date: Wed, 30 Jul 2025 12:43:44 +0800 Subject: [PATCH 04/11] fix: update frontiers home style --- src/components/home/frontiers.tsx | 37 ++++++++++++++++--------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/components/home/frontiers.tsx b/src/components/home/frontiers.tsx index 2355fe0c..43d50fda 100644 --- a/src/components/home/frontiers.tsx +++ b/src/components/home/frontiers.tsx @@ -90,32 +90,33 @@ const Frontiers = () => { {item.activities?.[0].min_ranking_grade || 'S'} )} -
-

{item.title}

-
{item.description.frontier_desc}
-
- {item.activities?.[0] && ( -
-
+
+

{item.title}

+
+
-
-
- - {item.activities?.[0].total_asset_amount || 0} - {item.activities?.[0].reward_asset_type} -
-
- - {item.activities?.[0].days_left || 0}D + {item.activities?.[0] ? ( +
+
+ + {item.activities?.[0].total_asset_amount || 0} + {item.activities?.[0].reward_asset_type} +
+
+ + {item.activities?.[0].days_left || 0}D +
-
+ ) : ( +
{item.description.frontier_desc}
+ )}
Start
- )} +
))} From 4597e998addab0a0f3bf3000ec0ed1c27b7569e7 Mon Sep 17 00:00:00 2001 From: yangxiaohu Date: Thu, 31 Jul 2025 15:13:19 +0800 Subject: [PATCH 05/11] fix: rm extra code --- src/router.tsx | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/router.tsx b/src/router.tsx index 0f745c8b..b0d0aa0d 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -3,7 +3,6 @@ import { lazy, useEffect } from 'react' // layouts import FrontierLayout from '@/layouts/frontier-layout' -// import SettingsLayout from '@/layouts/settings-layout' import UserInfoLayout from '@/layouts/userinfo-layout' import AppLayout from '@/layouts/app-layout' import ArenaLayout from '@/layouts/arena-layout' @@ -22,13 +21,6 @@ const NewJourney = lazy(() => import('@/views/new-journey')) const ActivityGroup = lazy(() => import('@/views/quest/activity-group')) const Activity = lazy(() => import('@/views/quest/activity')) -// settings -// const SettingAccount = lazy(() => import('@/views/settings/account')) -// const SettingReward = lazy(() => import('@/views/settings/reward')) -// const SettingReputation = lazy(() => import('@/views/settings/reputation')) -// const SettingUserNFT = lazy(() => import('@/views/settings/user-nft')) -// const SettingUserSBT = lazy(() => import('@/views/settings/user-sbt')) - // user info const UserInfo = lazy(() => import('@/views/userinfo/index')) const UserInfoReward = lazy(() => import('@/views/userinfo/reward')) @@ -122,13 +114,6 @@ export default function Router() { }> } /> - {/* }> - } /> - } /> - } /> - } /> */} - {/* } /> */} - {/* */} }> } /> } /> From f106bdc2dfca94fb86a12852570ccd14004b333c Mon Sep 17 00:00:00 2001 From: yangxiaohu Date: Thu, 31 Jul 2025 15:18:07 +0800 Subject: [PATCH 06/11] build: add github build flow config --- .github/workflows/release.yml | 166 ++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..e035c4f5 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,166 @@ +name: 构建编译 + +on: + workflow_dispatch: + inputs: + environment: + description: 'Deployment environment' + required: true + default: 'test' + type: choice + options: + - production + - test + +env: + NODE_VERSION: '22' + REGISTRY: registry-intl.ap-southeast-1.aliyuncs.com + IMAGE_NAME: codatta/codatta-frontier-website + +jobs: + # 编译和构建 + build: + name: Build Application + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Create .env file + run: | + BUILD_TIME=$(TZ=Asia/Shanghai date +"%Y-%m-%d-%H-%M-%S") + ENVIRONMENT=${{ github.event.inputs.environment || 'test' }} + + # 根据环境设置不同的配置 + if [ "$ENVIRONMENT" = "production" ]; then + CDN_ASSETS_PATH="${{ vars.PROD_CDN_ASSETS_PATH }}" + TG_BOT_ID="${{ vars.PROD_VITE_TG_BOT_ID }}" + GA_TRACKING_ID="${{ vars.PROD_VITE_GA_TRACKING_ID }}" + else + CDN_ASSETS_PATH="${{ vars.TEST_CDN_ASSETS_PATH }}" + TG_BOT_ID="${{ vars.TEST_VITE_TG_BOT_ID }}" + GA_TRACKING_ID="${{ vars.TEST_VITE_GA_TRACKING_ID }}" + fi + + cat > .env << EOF + CDN_ASSETS_PATH=$CDN_ASSETS_PATH + VITE_TG_BOT_ID=$TG_BOT_ID + VITE_GA_TRACKING_ID=$GA_TRACKING_ID + EOF + cat .env + echo "BUILD_TIME=$BUILD_TIME" >> $GITHUB_ENV + echo "ENVIRONMENT=$ENVIRONMENT" >> $GITHUB_ENV + + - name: Build project + run: npm run build + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: build-files + path: dist/ + retention-days: 30 + + # 上传到OSS + deploy-to-oss: + name: Deploy to OSS + runs-on: ubuntu-latest + needs: build + + steps: + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build-files + path: dist/ + + - name: Install ossutil + run: | + # Install ossutil directly from Alibaba Cloud + curl -L https://gosspublic.alicdn.com/ossutil/1.7.16/ossutil64 -o ossutil + chmod +x ossutil + sudo mv ossutil /usr/local/bin/ossutil + + - name: Configure ossutil + run: | + # Configure ossutil with credentials + ossutil config -e "${{ vars.OSS_ENDPOINT }}" -i "${{ secrets.OSS_ACCESS_KEY_ID }}" -k "${{ secrets.OSS_ACCESS_KEY_SECRET }}" + + - name: Upload to OSS + run: | + # Set OSS configuration based on environment + OSS_BUCKET="${{ vars.OSS_BUCKET }}" + OSS_REGION="${{ vars.OSS_REGION }}" + ENVIRONMENT="${{ github.event.inputs.environment || 'test' }}" + + # Determine CDN_ASSETS_PATH based on environment + if [ "$ENVIRONMENT" = "production" ]; then + CDN_ASSETS_PATH="${{ vars.PROD_CDN_ASSETS_PATH }}" + else + CDN_ASSETS_PATH="${{ vars.TEST_CDN_ASSETS_PATH }}" + fi + + # Upload files to OSS + ossutil cp -r dist/ oss://$OSS_BUCKET/$CDN_ASSETS_PATH/ --recursive + + echo "Deployed to: https://$OSS_BUCKET.${{ vars.OSS_ENDPOINT }}/$CDN_ASSETS_PATH/" + + # 构建Docker镜像 + build-docker: + name: Build Docker Image + runs-on: ubuntu-latest + needs: build + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build-files + path: dist/ + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Aliyun Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ secrets.ALIYUN_REGISTRY_USERNAME }} + password: ${{ secrets.ALIYUN_REGISTRY_PASSWORD }} + ecr: auto + + - name: Generate build time + id: build-time + run: echo "build-time=$(TZ=Asia/Shanghai date +"%Y-%m-%d-%H-%M-%S")" >> $GITHUB_OUTPUT + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=${{ github.event.inputs.environment }}-${{ steps.build-time.outputs.build-time }} + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max From fbcc37b9dd4211319071f3b1d21b95b55c856644 Mon Sep 17 00:00:00 2001 From: yangxiaohu Date: Thu, 31 Jul 2025 15:43:10 +0800 Subject: [PATCH 07/11] fix: fix style --- src/components/home/frontiers.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/home/frontiers.tsx b/src/components/home/frontiers.tsx index 43d50fda..e7485a13 100644 --- a/src/components/home/frontiers.tsx +++ b/src/components/home/frontiers.tsx @@ -2,8 +2,8 @@ import { message, Spin } from 'antd' import { useNavigate } from 'react-router-dom' import { useEffect, useMemo, useState } from 'react' -import arrowRight from '@/assets/icons/arrow-right.svg' -import badgeIcon from '@/assets/home/badge.svg' +import arrowRight from '@/assets/icons/arrow-right.svg?url' +import badgeIcon from '@/assets/home/badge.svg?url' import DollarCircle from '@/assets/home/dollar-circle.svg?react' import Hourglass from '@/assets/home/hourglass.svg?react' @@ -68,7 +68,7 @@ const Frontiers = () => { {displayFrontiers.map((item) => (
handleFrontierClick(item)} > Date: Thu, 31 Jul 2025 20:25:10 +0800 Subject: [PATCH 08/11] fix: reward_mode and activity list --- src/apis/frontiter.api.ts | 2 +- src/components/home/activity-info.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/apis/frontiter.api.ts b/src/apis/frontiter.api.ts index 99dd8771..134b4c17 100644 --- a/src/apis/frontiter.api.ts +++ b/src/apis/frontiter.api.ts @@ -190,7 +190,7 @@ class frontier { async getFrontierActivityInfo(data: { frontier_id: string status?: ActiveStatus - }): Promise> { + }): Promise> { const res = await this.request.post('/v2/frontier/activity/info', data) return res.data } diff --git a/src/components/home/activity-info.tsx b/src/components/home/activity-info.tsx index 07c58b48..699fe50e 100644 --- a/src/components/home/activity-info.tsx +++ b/src/components/home/activity-info.tsx @@ -15,7 +15,7 @@ export default function ActivityInfo({ className }: { className?: string }) { async function getFrontierActivityInfo(frontier_id: string) { const res = await frontierApi.getFrontierActivityInfo({ frontier_id }) if (res.errorCode === 0) { - setActivityInfoList(res.data[0]) + setActivityInfoList(res.data) console.log(res.data) } } @@ -54,7 +54,7 @@ export default function ActivityInfo({ className }: { className?: string }) { {item.reward_asset_type}
- {item.reward_mode !== 'EQUAL_SPLIT_ON_END' ? ( + {item.reward_mode === 'EQUAL_SPLIT_ON_END' ? (
Total Submissions
{formatNumber(item.submissions || 0)}
From 825409ef01e28a3833d0b5d1ffca6d9c60011605 Mon Sep 17 00:00:00 2001 From: Meow Lord Date: Thu, 31 Jul 2025 20:29:36 +0800 Subject: [PATCH 09/11] fix: fix frontier store --- src/stores/frontier.store.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stores/frontier.store.ts b/src/stores/frontier.store.ts index 2a29e661..491cbbd9 100644 --- a/src/stores/frontier.store.ts +++ b/src/stores/frontier.store.ts @@ -148,7 +148,7 @@ async function getFrontierActivities(data: { frontier_id: string; status?: Activ frontier_id: data.frontier_id, status: data.status }) - frontiersStore.frontierActivities = res.data[0] || [] + frontiersStore.frontierActivities = res.data || [] return res.data } From 2cd0bf1c333d3351b74c9f717af4e216c71c0574 Mon Sep 17 00:00:00 2001 From: Meow Lord Date: Thu, 31 Jul 2025 20:48:48 +0800 Subject: [PATCH 10/11] fix: fix svg vg --- src/components/home/frontiers.tsx | 2 +- src/vite-env.d.ts | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/home/frontiers.tsx b/src/components/home/frontiers.tsx index e7485a13..7a2aad1a 100644 --- a/src/components/home/frontiers.tsx +++ b/src/components/home/frontiers.tsx @@ -3,7 +3,7 @@ import { useNavigate } from 'react-router-dom' import { useEffect, useMemo, useState } from 'react' import arrowRight from '@/assets/icons/arrow-right.svg?url' -import badgeIcon from '@/assets/home/badge.svg?url' +import badgeIcon from '@/assets/home/badge.svg#file' import DollarCircle from '@/assets/home/dollar-circle.svg?react' import Hourglass from '@/assets/home/hourglass.svg?react' diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index 6a8856de..a516d9c6 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -10,4 +10,9 @@ interface Window { declare module '*.md' { const value: string export default value -} \ No newline at end of file +} + +declare module '*#file' { + const src: string + export default src +} From 97939cea24fffa2c6cc9f97982b50d6675aa352a Mon Sep 17 00:00:00 2001 From: Meow Lord Date: Thu, 31 Jul 2025 21:26:29 +0800 Subject: [PATCH 11/11] fix: fix mode description --- .github/workflows/release.yml | 2 +- src/components/home/activity-info.tsx | 24 ++++++++++++++---------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b929d015..6e61208b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,4 @@ -name: 构建编译 +name: Build Application on: workflow_dispatch: diff --git a/src/components/home/activity-info.tsx b/src/components/home/activity-info.tsx index 699fe50e..043ab9d6 100644 --- a/src/components/home/activity-info.tsx +++ b/src/components/home/activity-info.tsx @@ -92,7 +92,7 @@ export default function ActivityInfo({ className }: { className?: string }) {
)} - + ))} @@ -100,16 +100,20 @@ export default function ActivityInfo({ className }: { className?: string }) { ) } -const defaultRules = [ - 'Multiple valid submissions count for reward sharing', - 'Minimum data quality requirement: Grade S', - 'Below standard submissions receive points reward', - 'Quality assessment based on accuracy and completeness', - 'First come, first served: Fixed rewards for reaching baseline score during activity period. Once required quantity is reached, no more rewards will be distributed even if activity continues.Below standard gets points reward', - 'Divide and share mode: Multiple submissions valid, each counts for sharing. Below standard gets points reward.' -] +function getRulesText(activity: FrontierActivityInfoItem) { + return [ + 'Multiple valid submissions count for reward sharing', + `Minimum data quality requirement: Grade ${activity.min_ranking_grade}`, + 'Below standard submissions receive points reward', + 'Quality assessment based on accuracy and completeness', + activity.reward_mode === 'FIRST_COME_FIRST_SERVE' + ? 'First come, first served: Fixed rewards for reaching baseline score during activity period. Once required quantity is reached, no more rewards will be distributed even if activity continues.Below standard gets points reward' + : 'Divide and share mode: Multiple submissions valid, each counts for sharing. Below standard gets points reward.' + ] +} -function Rules({ rules = defaultRules }: { rules?: string[] }) { +function Rules({ activity }: { activity: FrontierActivityInfoItem }) { + const rules = getRulesText(activity) const [showRules, setShowRules] = useState(false) return (