+
+{{template "base/footer" .}}
diff --git a/templates/admin/resources/specification.tmpl b/templates/admin/resources/specification.tmpl
new file mode 100644
index 000000000..34992c5c9
--- /dev/null
+++ b/templates/admin/resources/specification.tmpl
@@ -0,0 +1,10 @@
+{{template "base/head" .}}
+
+ {{template "admin/navbar" .}}
+
+
+{{template "base/footer" .}}
diff --git a/web_src/vuepages/apis/modules/point.js b/web_src/vuepages/apis/modules/point.js
new file mode 100644
index 000000000..9ac9688cf
--- /dev/null
+++ b/web_src/vuepages/apis/modules/point.js
@@ -0,0 +1,41 @@
+import service from '../service';
+
+// 算力积分概要
+export const getPointAccount = () => {
+ return service({
+ url: '/reward/point/account',
+ method: 'get',
+ params: {},
+ });
+}
+
+// 算力积分获取、消耗明细
+// operate-INCREASE 表示获取明细 DECREASE表示消耗明细, page-当前页, pageSize-每页条数
+export const getPointList = (params) => {
+ return service({
+ url: '/reward/point/record/list',
+ method: 'get',
+ params,
+ });
+}
+
+// 管理员充值、扣减用户积分
+// TargetUserId, OperateType-INCREASE,DECREASE, Amount, Remark, RewardType-POINT
+export const setPointOperate = (data) => {
+ return service({
+ url: '/operation/reward/point/account/operate',
+ method: 'post',
+ data,
+ params: {}
+ });
+}
+
+// 算力积分页面
+export const getPoint = () => {
+ return service({
+ url: '/reward/point',
+ method: 'get',
+ params: {},
+ data: {},
+ });
+}
diff --git a/web_src/vuepages/apis/service.js b/web_src/vuepages/apis/service.js
new file mode 100644
index 000000000..292b9ef78
--- /dev/null
+++ b/web_src/vuepages/apis/service.js
@@ -0,0 +1,26 @@
+import axios from 'axios';
+
+const service = axios.create({
+ baseURL: '/',
+ timeout: 20000,
+});
+
+service.interceptors.request.use((config) => {
+ config.data && Object.assign(config.data, {
+ _csrf: window.config ? window.config.csrf : '',
+ });
+ config.params && Object.assign(config.params, {
+ _csrf: window.config ? window.config.csrf : '',
+ });
+ return config;
+}, (error) => {
+ return Promise.reject(error);
+});
+
+service.interceptors.response.use((response) => {
+ return response;
+}, (error) => {
+ return Promise.reject(error);
+});
+
+export default service;
diff --git a/web_src/vuepages/components/BaseDialog.vue b/web_src/vuepages/components/BaseDialog.vue
new file mode 100644
index 000000000..25744f908
--- /dev/null
+++ b/web_src/vuepages/components/BaseDialog.vue
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web_src/vuepages/const/index.js b/web_src/vuepages/const/index.js
new file mode 100644
index 000000000..7cc6cc636
--- /dev/null
+++ b/web_src/vuepages/const/index.js
@@ -0,0 +1,9 @@
+import { i18n } from '~/langs';
+
+export const SOURCE_TYPE = [{ k: 'ACCOMPLISH_TASK', v: i18n.t('accomplishTask') }, { k: 'ADMIN_OPERATE', v: i18n.t('adminOperate') }, { k: 'RUN_CLOUDBRAIN_TASK', v: i18n.t('runCloudBrainTask') }];
+export const CONSUME_STATUS = [{ k: 'OPERATING', v: i18n.t('operating') }, { k: 'SUCCEEDED', v: i18n.t('succeeded') }];
+export const POINT_ACTIONS = [
+ { k: 1, v: i18n.t('createPublicProject') }, { k: 6, v: i18n.t('dailyPutforwardTasks') }, { k: 7, v: i18n.t('dailyPR') }, { k: 10, v: i18n.t('comment') }, { k: 24, v: i18n.t('uploadDatasetFile') }, { k: 30, v: i18n.t('importNewModel') }, { k: 34, v: i18n.t('completeWechatCodeScanningVerification') },
+ { k: 35, v: i18n.t('dailyRunCloudbrainTasks') }, { k: 36, v: i18n.t('datasetRecommendedByThePlatform') }, { k: 37, v: i18n.t('submitNewPublicImage') }, { k: 38, v: i18n.t('imageRecommendedByThePlatform') }, { k: 39, v: i18n.t('firstChangeofAvatar') }, { k: 40, v: i18n.t('dailyCommit') },
+];
+export const JOB_TYPE = [{ k: 'DEBUG', v: i18n.t('debugTask') }, { k: 'TRAIN', v: i18n.t('trainTask') }, { k: 'INFERENCE', v: i18n.t('inferenceTask') }, { k: 'BENCHMARK', v: i18n.t('benchmarkTask') }];
diff --git a/web_src/vuepages/langs/config/en-US.js b/web_src/vuepages/langs/config/en-US.js
new file mode 100644
index 000000000..bfd193a95
--- /dev/null
+++ b/web_src/vuepages/langs/config/en-US.js
@@ -0,0 +1,70 @@
+const en = {
+ loading: 'Loading...',
+ noData: 'No Data',
+ date: 'Date',
+
+ accomplishTask: 'Accomplish Task',
+ adminOperate: 'Administrator Operation',
+ runCloudBrainTask: 'Run CloudBrain Task',
+ operating: 'Operating',
+ succeeded: 'Succeeded',
+ debugTask: 'Debug Task',
+ trainTask: 'Train Task',
+ inferenceTask: 'Inference Task',
+ benchmarkTask: 'Benchmark Task',
+ createPublicProject: 'Create Public Projects',
+ dailyPutforwardTasks: 'Daily Put Forward Tasks',
+ dailyPR: 'Daily PR',
+ comment: 'Comment',
+ uploadDatasetFile: 'Upload Dataset Files',
+ importNewModel: 'Import New Models',
+ completeWechatCodeScanningVerification: 'Complete Wechat Code Scanning Verification',
+ dailyRunCloudbrainTasks: 'Daily Run Cloudbrain Tasks',
+ datasetRecommendedByThePlatform: 'Dataset Recommended by the Platform',
+ submitNewPublicImage: 'Submit New Public Images',
+ imageRecommendedByThePlatform: 'Image Recommended by the Platform',
+ firstChangeofAvatar: 'First Change of Avatar',
+ dailyCommit: 'Daily Commit',
+ calcPointDetails: 'Calculation Points Details',
+ calcPointAcquisitionInstructions: 'Calculation Points Acquisition Instructions',
+ CurrAvailableCalcPoints: 'Currently Available Calculation Points',
+ totalGainCalcPoints: 'Total Gain of Calculation Points',
+ totalConsumeCalcPoints: 'Total Consume of Calculation Points',
+ gainDetail: 'Gain Detail',
+ consumeDetail: 'Consume Detail',
+ serialNumber: 'Serial Number',
+ time: 'Time',
+ scene: 'Scene',
+ behaviorOfPoint: 'Behavior Of Point',
+ explanation: 'Explanation',
+ points: 'Points',
+ status: 'Status',
+ runTime: 'Run Time',
+ taskName: 'Task Name',
+
+ createdRepository: 'created repository ',
+ openedIssue: 'opened issue ',
+ createdPullRequest: 'created pull request ',
+ commentedOnIssue: 'commented on issue ',
+ uploadDataset: 'upload dataset ',
+ createdNewModel: 'created new model ',
+ firstBindingWechatRewards: 'first binding wechat rewards',
+ created: 'created ',
+ type: ' type ',
+ dataset: 'dataset ',
+ setAsRecommendedDataset: ' was set as recommended dataset',
+ committedImage: 'committed image ',
+ image: 'image ',
+ setAsRecommendedImage: ' was set as recommended image',
+ updatedAvatar: 'updated avatar',
+ pushedBranch: 'pushed to {branch} at ',
+ dailyMaxTips: `can't get full points when reach the daily upper limit`,
+ memory: 'Memory',
+ sharedMemory: 'Shared Memory',
+ ';': ', ',
+
+ noPointGainRecord: 'No Point Earn Record Yet',
+ noPointConsumeRecord: 'No Point Consume Record Yet',
+}
+
+export default en;
diff --git a/web_src/vuepages/langs/config/zh-CN.js b/web_src/vuepages/langs/config/zh-CN.js
new file mode 100644
index 000000000..9f8ecff5b
--- /dev/null
+++ b/web_src/vuepages/langs/config/zh-CN.js
@@ -0,0 +1,70 @@
+const zh = {
+ loading: '加载中...',
+ noData: '暂无数据',
+ date: '日期',
+
+ accomplishTask: '积分任务',
+ adminOperate: '管理员操作',
+ runCloudBrainTask: '运行云脑任务',
+ operating: '消耗中',
+ succeeded: '已完成',
+ debugTask: '调试任务',
+ trainTask: '训练任务',
+ inferenceTask: '推理任务',
+ benchmarkTask: '评测任务',
+ createPublicProject: '创建公开项目',
+ dailyPutforwardTasks: '每日提出任务',
+ dailyPR: '每日提出PR',
+ comment: '发表评论',
+ uploadDatasetFile: '上传数据集文件',
+ importNewModel: '导入新模型',
+ completeWechatCodeScanningVerification: '完成微信扫码验证',
+ dailyRunCloudbrainTasks: '每日运行云脑任务',
+ datasetRecommendedByThePlatform: '数据集被平台推荐',
+ submitNewPublicImage: '提交新公开镜像',
+ imageRecommendedByThePlatform: '镜像被平台推荐',
+ firstChangeofAvatar: '首次更换头像',
+ dailyCommit: '每日commit',
+ calcPointDetails: '算力积分明细',
+ calcPointAcquisitionInstructions: '积分获取说明',
+ CurrAvailableCalcPoints: '当前可用算力积分(分)',
+ totalGainCalcPoints: '总获取算力积分(分)',
+ totalConsumeCalcPoints: '总消耗算力积分(分)',
+ gainDetail: '获取明细',
+ consumeDetail: '消耗明细',
+ serialNumber: '流水号',
+ time: '时间',
+ scene: '场景',
+ behaviorOfPoint: '积分行为',
+ explanation: '说明',
+ points: '积分',
+ status: '状态',
+ runTime: '运行时长',
+ taskName: '任务名称',
+
+ createdRepository: '创建了项目',
+ openedIssue: '创建了任务',
+ createdPullRequest: '创建了合并请求',
+ commentedOnIssue: '评论了任务',
+ uploadDataset: '上传了数据集文件',
+ createdNewModel: '导入了新模型',
+ firstBindingWechatRewards: '首次绑定微信奖励',
+ created: '创建了',
+ type: '类型',
+ dataset: '数据集',
+ setAsRecommendedDataset: '被设置为推荐数据集',
+ committedImage: '提交了镜像',
+ image: '镜像',
+ setAsRecommendedImage: '被设置为推荐镜像',
+ updatedAvatar: '更新了头像',
+ pushedBranch: '推送了{branch}分支代码到',
+ dailyMaxTips: '达到每日上限积分,不能拿满分',
+ memory: '内存',
+ sharedMemory: '共享内存',
+ ';': ';',
+
+ noPointGainRecord: '还没有积分获取记录',
+ noPointConsumeRecord: '还没有积分消耗记录',
+}
+
+export default zh;
diff --git a/web_src/vuepages/langs/index.js b/web_src/vuepages/langs/index.js
new file mode 100644
index 000000000..9cfecd9a0
--- /dev/null
+++ b/web_src/vuepages/langs/index.js
@@ -0,0 +1,16 @@
+import Vue from 'vue';
+import VueI18n from 'vue-i18n';
+import jsCookie from 'js-cookie';
+import zh from './config/zh-CN';
+import en from './config/en-US';
+
+Vue.use(VueI18n);
+
+export const lang = jsCookie.get('lang') || 'zh-CN';
+export const i18n = new VueI18n({
+ locale: lang,
+ messages: {
+ 'zh-CN': zh,
+ 'en-US': en
+ },
+});
diff --git a/web_src/vuepages/pages/resources/components/QueueDialog.vue b/web_src/vuepages/pages/resources/components/QueueDialog.vue
new file mode 100644
index 000000000..5f55945da
--- /dev/null
+++ b/web_src/vuepages/pages/resources/components/QueueDialog.vue
@@ -0,0 +1,196 @@
+
+
+
+
+
diff --git a/web_src/vuepages/pages/resources/queue/index.vue b/web_src/vuepages/pages/resources/queue/index.vue
new file mode 100644
index 000000000..ea423af18
--- /dev/null
+++ b/web_src/vuepages/pages/resources/queue/index.vue
@@ -0,0 +1,194 @@
+
+
+
资源池(队列)
+
+
+
+
+
+
+
+ {{ scope.row.userName }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.amount }}
+
+
+
+
+ {{ scope.row.blance }}
+
+
+
+
+ {{ scope.row.blance }}
+
+
+
+
+ {{ scope.row.blance }}
+
+
+
+ {{
+ loading ? '加载中...' : '暂无数据'
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web_src/vuepages/pages/resources/queue/vp-resources-queue.js b/web_src/vuepages/pages/resources/queue/vp-resources-queue.js
new file mode 100644
index 000000000..48e542500
--- /dev/null
+++ b/web_src/vuepages/pages/resources/queue/vp-resources-queue.js
@@ -0,0 +1,17 @@
+import Vue from 'vue';
+import ElementUI from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+import localeEn from 'element-ui/lib/locale/lang/en';
+import localeZh from 'element-ui/lib/locale/lang/zh-CN';
+import { i18n, lang } from '~/langs';
+import App from './index.vue';
+
+Vue.use(ElementUI, {
+ locale: lang === 'zh-CN' ? localeZh : localeEn,
+ size: 'small',
+});
+
+new Vue({
+ i18n,
+ render: (h) => h(App),
+}).$mount('#__vue-root');
diff --git a/web_src/vuepages/pages/resources/scene/index.vue b/web_src/vuepages/pages/resources/scene/index.vue
new file mode 100644
index 000000000..ce898c373
--- /dev/null
+++ b/web_src/vuepages/pages/resources/scene/index.vue
@@ -0,0 +1,43 @@
+
+
+ scene
+
+
+
+
+
+
diff --git a/web_src/vuepages/pages/resources/scene/vp-resources-scene.js b/web_src/vuepages/pages/resources/scene/vp-resources-scene.js
new file mode 100644
index 000000000..48e542500
--- /dev/null
+++ b/web_src/vuepages/pages/resources/scene/vp-resources-scene.js
@@ -0,0 +1,17 @@
+import Vue from 'vue';
+import ElementUI from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+import localeEn from 'element-ui/lib/locale/lang/en';
+import localeZh from 'element-ui/lib/locale/lang/zh-CN';
+import { i18n, lang } from '~/langs';
+import App from './index.vue';
+
+Vue.use(ElementUI, {
+ locale: lang === 'zh-CN' ? localeZh : localeEn,
+ size: 'small',
+});
+
+new Vue({
+ i18n,
+ render: (h) => h(App),
+}).$mount('#__vue-root');
diff --git a/web_src/vuepages/pages/resources/specification/index.vue b/web_src/vuepages/pages/resources/specification/index.vue
new file mode 100644
index 000000000..b85312d3c
--- /dev/null
+++ b/web_src/vuepages/pages/resources/specification/index.vue
@@ -0,0 +1,43 @@
+
+
+ specification
+
+
+
+
+
+
diff --git a/web_src/vuepages/pages/resources/specification/vp-resources-specification.js b/web_src/vuepages/pages/resources/specification/vp-resources-specification.js
new file mode 100644
index 000000000..48e542500
--- /dev/null
+++ b/web_src/vuepages/pages/resources/specification/vp-resources-specification.js
@@ -0,0 +1,17 @@
+import Vue from 'vue';
+import ElementUI from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+import localeEn from 'element-ui/lib/locale/lang/en';
+import localeZh from 'element-ui/lib/locale/lang/zh-CN';
+import { i18n, lang } from '~/langs';
+import App from './index.vue';
+
+Vue.use(ElementUI, {
+ locale: lang === 'zh-CN' ? localeZh : localeEn,
+ size: 'small',
+});
+
+new Vue({
+ i18n,
+ render: (h) => h(App),
+}).$mount('#__vue-root');
diff --git a/web_src/vuepages/pages/reward/point/utils.js b/web_src/vuepages/pages/reward/point/utils.js
new file mode 100644
index 000000000..fed9e48ba
--- /dev/null
+++ b/web_src/vuepages/pages/reward/point/utils.js
@@ -0,0 +1,148 @@
+
+import { formatDate } from 'element-ui/lib/utils/date-util';
+import { SOURCE_TYPE, CONSUME_STATUS, POINT_ACTIONS, JOB_TYPE } from '~/const';
+import { i18n } from '~/langs';
+
+const getSourceType = (key) => {
+ const find = SOURCE_TYPE.filter(item => item.k === key);
+ return find.length ? find[0].v : key;
+};
+
+const getConsumeStatus = (key) => {
+ const find = CONSUME_STATUS.filter(item => item.k === key);
+ return find.length ? find[0].v : key;
+};
+
+const getPointAction = (key) => {
+ const find = POINT_ACTIONS.filter(item => item.k === key);
+ return find.length ? find[0].v : key;
+};
+
+const getJobType = (key) => {
+ const find = JOB_TYPE.filter(item => item.k === key);
+ return find.length ? find[0].v : key;
+};
+
+const getJobTypeLink = (record, type) => {
+ let link = type === 'INCREASE' ? record.Action.RepoLink : '/' + record.Cloudbrain.RepoFullName;
+ const cloudbrain = type === 'INCREASE' ? record.Action?.Cloudbrain : record.Cloudbrain;
+ switch (cloudbrain?.JobType) {
+ case 'DEBUG':
+ if (cloudbrain.ComputeResource === 'CPU/GPU') {
+ link += `/cloudbrain/${cloudbrain.ID}`;
+ } else {
+ link += `/modelarts/notebook/${cloudbrain.ID}`;
+ }
+ break;
+ case 'TRAIN':
+ if (cloudbrain.Type === 1) {
+ link += `/modelarts/train-job/${cloudbrain.JobID}`;
+ } else if (cloudbrain.Type === 0) {
+ link += `/cloudbrain/train-job/${cloudbrain.JobID}`;
+ } else if (cloudbrain.Type === 2) {
+ link += `/grampus/train-job/${cloudbrain.JobID}`;
+ }
+ break;
+ case 'INFERENCE':
+ link += `/modelarts/inference-job/${cloudbrain.JobID}`;
+ break;
+ case 'BENCHMARK':
+ link += `/cloudbrain/benchmark/${cloudbrain.ID}`;
+ break;
+ default:
+ break;
+ };
+ return link;
+};
+
+export const getRewardPointRecordInfo = (record) => {
+ const out = {
+ sn: record.SerialNo,
+ date: formatDate(new Date(record.LastOperateDate * 1000), 'yyyy-MM-dd HH:mm:ss'),
+ _status: record.Status,
+ status: getConsumeStatus(record.Status) || '--',
+ statusColor: record.Status === 'OPERATING' ? 'rgb(33, 186, 69)' : '',
+ _sourceType: record.SourceType,
+ sourceType: getSourceType(record.SourceType),
+ duration: record?.Cloudbrain?.Duration || '--',
+ taskName: record?.Cloudbrain?.DisplayJobName || '--',
+ taskId: record?.Cloudbrain?.ID,
+ action: record?.Action?.OpType ? getPointAction(record.Action.OpType) : '--',
+ remark: record.Remark,
+ amount: record.Amount,
+ };
+ if (record.OperateType === 'INCREASE') {
+ if (record.SourceType === 'ADMIN_OPERATE') {
+ out.remark = record.Remark;
+ } else if (record.SourceType === 'ACCOMPLISH_TASK') {
+ switch (record?.Action?.OpType) {
+ case 1: // 创建公开项目 - 创建了项目OpenI/aiforge
+ out.remark = `${i18n.t('createdRepository')}
${record.Action.ShortRepoFullDisplayName}`;
+ break;
+ case 6: // 每日提出任务 - 创建了任务PCL-Platform.Intelligence/AISynergy#19
+ out.remark = `${i18n.t('openedIssue')}
${record.Action.ShortRepoFullDisplayName}#${record.Action.IssueInfos[0]}`;
+ break;
+ case 7: // 每日提出PR - 创建了合并请求OpenI/aiforge#1
+ out.remark = `${i18n.t('createdPullRequest')}
${record.Action.ShortRepoFullDisplayName}#${record.Action.IssueInfos[0]}`;
+ break;
+ case 10: // 发表评论 - 评论了任务PCL-Platform.Intelligence/AISynergy#19
+ out.remark = `${i18n.t('commentedOnIssue')}
${record.Action.ShortRepoFullDisplayName}#${record.Action.IssueInfos[0]}`;
+ break;
+ case 24: // 上传数据集文件 - 上传了数据集文件MMISTData.zip
+ out.remark = `${i18n.t('uploadDataset')}
${record.Action.RefName}`;
+ break;
+ case 30: // 导入新模型 - 导入了新模型resnet50_qx7l
+ out.remark = `${i18n.t('createdNewModel')}
${record.Action.RefName}`;
+ break;
+ case 34: // 完成微信扫码验证 - 首次绑定微信奖励
+ out.remark = `${i18n.t('firstBindingWechatRewards')}`;
+ break;
+ case 35: // 每日运行云脑任务 - 创建了(CPU/GPU/NPU)类型(调试/训练/推理/评测)任务tangl202204131431995
+ out.remark = `${i18n.t('created')}${record.Action?.Cloudbrain?.ComputeResource}${i18n.t('type')}${getJobType(record.Action?.Cloudbrain?.JobType)}
${record.Action.RefName}`;
+ break;
+ case 36: // 数据集被平台推荐 - 数据集XXX被设置为推荐数据集
+ out.remark = `${i18n.t('dataset')}
${record.Action.Content && record.Action.Content.split('|')[1]}${i18n.t('setAsRecommendedDataset')}`;
+ break;
+ case 37: // 提交新公开镜像 - 提交了镜像jiangxiang_ceshi_tang03
+ out.remark = `${i18n.t('committedImage')}
${record.Action.Content && record.Action.Content.split('|')[1]}`;
+ break;
+ case 38: // 镜像被平台推荐 - 镜像XXX被设置为推荐镜像
+ out.remark = `${i18n.t('image')}
${record.Action.Content && record.Action.Content.split('|')[1]}${i18n.t('setAsRecommendedImage')}`;
+ break;
+ case 39: // 首次更换头像 - 更新了头像
+ out.remark = `${i18n.t('updatedAvatar')}`;
+ break;
+ case 40: // 每日commit - 推送了xxxx分支的代码到OpenI/aiforge
+ const words = record.Action.RefName.split('/');
+ const branch = words[words.length - 1];
+ out.remark = `${i18n.t('pushedBranch', {
+ branch: `
${branch}`
+ })}
${record.Action.ShortRepoFullDisplayName}`;
+ break;
+ default:
+ break;
+ }
+ } else if (record.SourceType === 'RUN_CLOUDBRAIN_TASK') {
+ //
+ }
+ if (record.LossAmount !== 0) {
+ out.amount = record.Amount;
+ out.remark += `${out.remark ? i18n.t(';') : ''}${i18n.t('dailyMaxTips')}`;
+ }
+ } else if (record.OperateType === 'DECREASE') {
+ if (record.SourceType === 'ADMIN_OPERATE') {
+ out.remark = record.Remark;
+ } else if (record.SourceType === 'ACCOMPLISH_TASK') {
+ //
+ } else if (record.SourceType === 'RUN_CLOUDBRAIN_TASK') {
+ out.taskName = `
${record?.Cloudbrain?.DisplayJobName}`;
+ if (record?.Cloudbrain?.ComputeResource === 'CPU/GPU') {
+ const resourceSpec = record?.Cloudbrain?.ResourceSpec?.ResourceSpec;
+ out.remark = `【${getJobType(record?.Cloudbrain?.JobType)}】【${record?.Cloudbrain?.ComputeResource}】【GPU: ${resourceSpec?.gpu}, CPU: ${resourceSpec?.cpu}, ${i18n.t('memory')}: ${(resourceSpec?.memMiB / 1024).toFixed(2)}GB, ${i18n.t('sharedMemory')}: ${(resourceSpec?.shareMemMiB / 1024).toFixed(2)}GB】`;
+ } else {
+ out.remark = `【${getJobType(record?.Cloudbrain?.JobType)}】【${record?.Cloudbrain?.ComputeResource}】【${record?.Cloudbrain?.ResourceSpec.FlavorInfo.desc}】`;
+ }
+ }
+ }
+ return out;
+};
diff --git a/web_src/vuepages/pages/reward/point/vp-point.js b/web_src/vuepages/pages/reward/point/vp-point.js
new file mode 100644
index 000000000..8b27917c3
--- /dev/null
+++ b/web_src/vuepages/pages/reward/point/vp-point.js
@@ -0,0 +1,16 @@
+import Vue from 'vue';
+import ElementUI from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+import localeEn from 'element-ui/lib/locale/lang/en';
+import localeZh from 'element-ui/lib/locale/lang/zh-CN';
+import { i18n, lang } from '~/langs';
+import App from './vp-point.vue';
+
+Vue.use(ElementUI, {
+ locale: lang === 'zh-CN' ? localeZh : localeEn
+});
+
+new Vue({
+ i18n,
+ render: (h) => h(App),
+}).$mount('#__vue-root');
diff --git a/web_src/vuepages/pages/reward/point/vp-point.vue b/web_src/vuepages/pages/reward/point/vp-point.vue
new file mode 100644
index 000000000..34663d653
--- /dev/null
+++ b/web_src/vuepages/pages/reward/point/vp-point.vue
@@ -0,0 +1,308 @@
+
+
+
+
+
+
+
{{ summaryInfo.available }}
+
{{ $t('CurrAvailableCalcPoints') }}
+
+
+
+
{{ summaryInfo.gain }}
+
{{ $t('totalGainCalcPoints') }}
+
+
+
{{ summaryInfo.used }}
+
{{ $t('totalConsumeCalcPoints') }}
+
+
+
+
+ {{ $t('gainDetail') }}
+
+
+ {{ $t('consumeDetail') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ loading ? $t('loading') : $t('noData') }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.status }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ loading ? $t('loading') : $t('noData') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/webpack.config.js b/webpack.config.js
index d209a1683..917abf62a 100755
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -29,6 +29,11 @@ for (const path of stadalonePaths) {
standalone[parse(path).name] = [path];
}
+const vuePages = {};
+for (const path of glob('web_src/vuepages/**/vp-*.js')) {
+ vuePages[parse(path).name] = [path];
+}
+
const isProduction = process.env.NODE_ENV !== 'development';
module.exports = {
@@ -44,6 +49,7 @@ module.exports = {
icons: glob('node_modules/@primer/octicons/build/svg/**/*.svg'),
...standalone,
...themes,
+ ...vuePages,
},
devtool: false,
output: {
@@ -267,6 +273,7 @@ module.exports = {
symlinks: false,
alias: {
vue$: 'vue/dist/vue.esm.js', // needed because vue's default export is the runtime only
+ '~': resolve(__dirname, 'web_src/vuepages'),
},
extensions: ['.tsx', '.ts', '.js']
},
diff --git a/webpack_pro.config.js b/webpack_pro.config.js
index 7ea94bbb9..d12295c0a 100755
--- a/webpack_pro.config.js
+++ b/webpack_pro.config.js
@@ -29,6 +29,11 @@ for (const path of stadalonePaths) {
standalone[parse(path).name] = [path];
}
+const vuePages = {};
+for (const path of glob('web_src/vuepages/**/vp-*.js')) {
+ vuePages[parse(path).name] = [path];
+}
+
const isProduction = process.env.NODE_ENV !== 'development';
module.exports = {
@@ -44,6 +49,7 @@ module.exports = {
icons: glob('node_modules/@primer/octicons/build/svg/**/*.svg'),
...standalone,
...themes,
+ ...vuePages
},
devtool: false,
output: {
@@ -267,6 +273,7 @@ module.exports = {
symlinks: false,
alias: {
vue$: 'vue/dist/vue.esm.js', // needed because vue's default export is the runtime only
+ '~': resolve(__dirname, 'web_src/vuepages'),
},
extensions: ['.tsx', '.ts', '.js']
},