Commit 513ea508 authored by hanfeng zhang's avatar hanfeng zhang

Merge branch 'main' of gitlab.33.cn:HF_web/NFT

parents 8a505487 649c6831
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
"core-js": "^3.6.5", "core-js": "^3.6.5",
"epic-spinners": "^1.1.0", "epic-spinners": "^1.1.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"md5": "^2.3.0",
"register-service-worker": "^1.7.1", "register-service-worker": "^1.7.1",
"validator": "^13.6.0", "validator": "^13.6.0",
"vant": "^2.12.22", "vant": "^2.12.22",
...@@ -30,6 +31,7 @@ ...@@ -30,6 +31,7 @@
"devDependencies": { "devDependencies": {
"@types/async": "^3.2.7", "@types/async": "^3.2.7",
"@types/lodash": "^4.14.170", "@types/lodash": "^4.14.170",
"@types/md5": "^2.3.1",
"@types/validator": "^13.6.3", "@types/validator": "^13.6.3",
"@typescript-eslint/eslint-plugin": "^4.18.0", "@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0", "@typescript-eslint/parser": "^4.18.0",
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
<input v-else-if="type === 'input-num'" <input v-else-if="type === 'input-num'"
:value="inputValue" :value="inputValue"
type="number" type="number"
:disabled="disabled"
@input="handleInput" @input="handleInput"
class="bg-transparent" class="bg-transparent"
:placeholder="placeholder" :placeholder="placeholder"
...@@ -50,6 +51,7 @@ ...@@ -50,6 +51,7 @@
<div class="flex flex-row items-center"> <div class="flex flex-row items-center">
<input <input
@click="eventEmit(type)" @click="eventEmit(type)"
:disabled="true"
v-if="$store.state.create.pickedList.length === 0" v-if="$store.state.create.pickedList.length === 0"
type="text" type="text"
class="bg-transparent" class="bg-transparent"
...@@ -94,7 +96,7 @@ ...@@ -94,7 +96,7 @@
> >
{{ name }} {{ name }}
</div> </div>
<div :data-clipboard-text="name" ref="btn" @click="handleClickCopy"> <div :data-clipboard-text="name" ref="btn" @click="handleClickCopy" class="ml-1">
<app-icon name="icon-fuzhi" size="18px"></app-icon> <app-icon name="icon-fuzhi" size="18px"></app-icon>
</div> </div>
</div> </div>
......
<template>
<div class="el-skeleton is-animated">
<div class="el-skeleton__item w-full" :class="_class" :style="_style"></div>
</div>
</template>
<script lang="ts">
import Vue from "vue";
export default Vue.extend({
props: ["_class", "_style"],
});
</script>
<style lang="less" scoped>
.el-skeleton__item {
background: #f2f2f2;
display: inline-block;
border-radius: 4px;
}
.el-skeleton.is-animated .el-skeleton__item {
background: linear-gradient(90deg, #0c0b31 25%, #282740 37%, #0c0b31 63%);
background-size: 400% 100%;
animation: el-skeleton-loading 1.4s ease infinite;
}
@keyframes el-skeleton-loading {
0% {
background-position: 100% 50%;
}
to {
background-position: 0 50%;
}
}
</style>
\ No newline at end of file
<template>
<div>
<SkeletonRect _class="oneSkeleton" />
<div class="flex justify-between mt-2">
<div v-for="n in 4" :key="n">
<SkeletonRect _class="circleSkeleton" />
<SkeletonRect _class="paraSkeleton" />
</div>
</div>
<div class="flex justify-between mt-3 items-center">
<SkeletonRect _class="circle2Skeleton" class="mr-2" />
<div class="flex-grow mr-6">
<SkeletonRect _class="paraSkeleton" />
<SkeletonRect _class="paraSkeleton" />
</div>
</div>
<div class="mt-3">
<SkeletonRect _class="para2Skeleton" />
<SkeletonRect _class="para2Skeleton" />
<SkeletonRect _class="para2Skeleton" />
<SkeletonRect _class="para2Skeleton" />
</div>
<SkeletonRect _class="twoSkeleton mt-8" />
</div>
</template>
<script>
import Vue from "vue";
import SkeletonRect from "./Rect.vue";
export default Vue.extend({
components: {
SkeletonRect,
},
});
</script>
<style lang="less">
.oneSkeleton {
height: 191px;
}
.circleSkeleton {
width: 64px !important;
height: 64px !important;
border-radius: 100% !important;
}
.circle2Skeleton {
width: 48px !important;
height: 48px !important;
border-radius: 100% !important;
}
.paraSkeleton {
height: 20px;
}
.para2Skeleton {
height: 30px;
}
.twoSkeleton {
height: 400px;
}
</style>
\ No newline at end of file
import { Common } from './common' import { Common } from './common'
import { NFTService } from './nftService' import { NFTService } from './nftService/nftService'
import {UserService} from './userService' import {UserService} from './userService'
......
import { Service } from './Service' import { Service } from '../Service'
import { token } from '@/util/userInfoUtils' import { token } from '@/util/userInfoUtils'
import { iSaveData } from './types'
export class NFTService extends Service { export class NFTService extends Service {
router = { router = {
getMyList: { getMyList: {
...@@ -23,6 +24,10 @@ export class NFTService extends Service { ...@@ -23,6 +24,10 @@ export class NFTService extends Service {
path: '/label/list', path: '/label/list',
dataType: 'application/x-www-form-urlencoded', dataType: 'application/x-www-form-urlencoded',
}, },
ossPolicy: {
path: '/oss/policy',
dataType: 'application/x-www-form-urlencoded',
},
getMd5: { path: '/nft/file/md5', dataType: 'multipart/form-data' }, getMd5: { path: '/nft/file/md5', dataType: 'multipart/form-data' },
save: { path: '/nft/save', dataType: 'multipart/form-data' }, save: { path: '/nft/save', dataType: 'multipart/form-data' },
publish: { path: '/nft/publish', dataType: 'application/json' }, publish: { path: '/nft/publish', dataType: 'application/json' },
...@@ -30,23 +35,21 @@ export class NFTService extends Service { ...@@ -30,23 +35,21 @@ export class NFTService extends Service {
path: '/category/list', path: '/category/list',
dataType: 'application/x-www-form-urlencoded', dataType: 'application/x-www-form-urlencoded',
}, },
editCollection:{ editCollection: {
path: '/collection/add', path: '/collection/add',
dataType: 'application/x-www-form-urlencoded' dataType: 'application/x-www-form-urlencoded',
}, },
getCollectionList:{ getCollectionList: {
path: '/collection/list', path: '/collection/list',
dataType: 'application/x-www-form-urlencoded', dataType: 'application/x-www-form-urlencoded',
} },
} }
constructor() { constructor() {
super() super()
} }
private getAuth() {
private getAuth(){ return 'Bearer ' + token.getToken()
return 'Bearer '+ token.getToken()
} }
/** /**
...@@ -54,13 +57,12 @@ export class NFTService extends Service { ...@@ -54,13 +57,12 @@ export class NFTService extends Service {
* @param id * @param id
* @returns * @returns
*/ */
async getNFTdetail(id: number):Promise<any>{ async getNFTdetail(id: number): Promise<any> {
return await this.service.get(this.router.detail.path+'/'+id,{ return await this.service.get(this.router.detail.path + '/' + id, {
headers: { headers: {
Authorization: this.getAuth(), Authorization: this.getAuth(),
'Content-Type': this.router.detail.dataType, 'Content-Type': this.router.detail.dataType,
}, },
}) })
} }
...@@ -69,30 +71,31 @@ export class NFTService extends Service { ...@@ -69,30 +71,31 @@ export class NFTService extends Service {
* @param id * @param id
* @returns * @returns
*/ */
async editCollection(id:number){ async editCollection(id: number) {
return await this.service.post(this.router.editCollection.path,{},{ return await this.service.post(
this.router.editCollection.path,
{},
{
headers: { headers: {
Authorization: this.getAuth(), Authorization: this.getAuth(),
'Content-Type': this.router.editCollection.dataType, 'Content-Type': this.router.editCollection.dataType,
}, },
params:{ params: {
id:id id: id,
} },
}) },
)
} }
async getCollection(): Promise<any[]> {
async getCollection():Promise<any[]>{ return await this.service.get(this.router.getCollectionList.path, {
return await this.service.get(this.router.getCollectionList.path,{
headers: { headers: {
Authorization: this.getAuth(), Authorization: this.getAuth(),
'Content-Type': this.router.editCollection.dataType, 'Content-Type': this.router.editCollection.dataType,
} },
}) })
} }
/** /**
* *
* @returns 获取剧目主题表 * @returns 获取剧目主题表
...@@ -118,7 +121,7 @@ export class NFTService extends Service { ...@@ -118,7 +121,7 @@ export class NFTService extends Service {
* @param categoryId * @param categoryId
* @returns * @returns
*/ */
async getMyList(categoryId?: number):Promise<any> { async getMyList(categoryId?: number): Promise<any> {
return await this.service.get(this.router.getMyList.path, { return await this.service.get(this.router.getMyList.path, {
headers: { headers: {
Authorization: this.getAuth(), Authorization: this.getAuth(),
...@@ -181,7 +184,7 @@ export class NFTService extends Service { ...@@ -181,7 +184,7 @@ export class NFTService extends Service {
/** /**
* 获取md5 * 获取md5
* @param id *
*/ */
async getMd5(file: File) { async getMd5(file: File) {
const fd = new FormData() const fd = new FormData()
...@@ -195,6 +198,35 @@ export class NFTService extends Service { ...@@ -195,6 +198,35 @@ export class NFTService extends Service {
} }
/** /**
* 完成OSS签名
*/
async ossPolicy() {
const ret = await this.service.get(this.router.ossPolicy.path, {
headers: {
Authorization: this.getAuth(),
'Content-Type': this.router.ossPolicy.dataType,
},
})
return ret
}
async uploadFileToOss(file: File, data: any) {
const { accessid, dir, expire, host, policy, signature } = data as any
const fd = new FormData()
fd.append('name', file.name)
fd.append('key', dir + '${filename}')
fd.append('policy', policy)
fd.append('OSSAccessKeyId', accessid)
fd.append('success_action_status', '200')
fd.append('signature', signature)
fd.append('file', file)
return await fetch(host, {
method: 'POST',
body: fd,
})
}
/**
* 发布 * 发布
* @param id * @param id
*/ */
...@@ -217,27 +249,13 @@ export class NFTService extends Service { ...@@ -217,27 +249,13 @@ export class NFTService extends Service {
* @param id * @param id
*/ */
async save( async save(data: iSaveData) {
author: string,
categoryId: number,
fileHash: string,
isArchives: number,
name: string,
synopsis: string,
theme: string,
file: File,
isGrant: number,
) {
const fd = new FormData() const fd = new FormData()
fd.append('author', author)
fd.append('categoryId', categoryId.toString()) Object.keys(data).forEach((keyName) => {
fd.append('fileHash', fileHash) const value = data[keyName as keyof iSaveData]
fd.append('isArchives', isArchives.toString()) fd.append(keyName, typeof value === 'number' ? String(value) : value)
fd.append('name', name) })
fd.append('synopsis', synopsis)
fd.append('theme', theme)
fd.append('file', file)
fd.append('isGrant', String(isGrant))
return (await this.service.post(this.router.save.path, fd, { return (await this.service.post(this.router.save.path, fd, {
headers: { headers: {
......
export interface iSaveData {
author: string
categoryId: number
fileHash: string
isArchives: number
name: string
synopsis: string
theme: string
isGrant: number
fileUrl?: string
fileName?:string
}
import Vue from 'vue' import Vue from 'vue'
import { Common } from './service/common' import { Common } from './service/common'
import { Service } from './service/index' import { Service } from './service/index'
import { NFTService } from './service/nftService' import { NFTService } from './service/nftService/nftService'
import { UserService } from './service/userService' import { UserService } from './service/userService'
import { UTIL_INTERFACE } from '@/util/util.types' import { UTIL_INTERFACE } from '@/util/util.types'
import VueRouter, { Route } from 'vue-router' import VueRouter, { Route } from 'vue-router'
......
*{ * {
margin: 0; margin: 0;
padding: 0 padding: 0;
} }
body{ body {
background-color:#1D2649; background-color: #1d2649;
} }
.van-tabs__nav{ .van-tabs__nav {
background-color: transparent !important; background-color: transparent !important;
} }
.van-tabs__line{ .van-tabs__line {
display: none; display: none;
} }
.van-tab--active{ .van-tab--active {
color: #EEF1F6 !important; color: #eef1f6 !important;
} }
.van-badge{ .van-badge {
background-color:#ED6F6F !important; background-color: #ed6f6f !important;
} }
.list-container{ .list-container {
height: 100vh - 390px; height: 100vh - 390px;
overflow-y: scroll; overflow-y: scroll;
} }
.van-overlay{ .van-overlay {
background-color: rgba(10,14,35,.95); background-color: rgba(10, 14, 35, 0.95);
} }
.fade-enter-active, .fade-enter-active,
...@@ -38,81 +37,86 @@ body{ ...@@ -38,81 +37,86 @@ body{
/* 可以设置不同的进入和离开动画 */ /* 可以设置不同的进入和离开动画 */
/* 设置持续时间和动画函数 */ /* 设置持续时间和动画函数 */
.slide-fade-enter-active { .slide-fade-enter-active {
transition: all .3s ease; transition: all 0.3s ease;
} }
.slide-fade-leave-active { .slide-fade-leave-active {
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0); transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);
} }
.slide-fade-enter, .slide-fade-leave-to .slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active for below version 2.1.8 */ { /* .slide-fade-leave-active for below version 2.1.8 */ {
transform: translateX(10px); transform: translateX(10px);
opacity: 0; opacity: 0;
} }
.step-progress__step--valid span{ .step-progress__step--valid span {
font-size: 12px !important; font-size: 12px !important;
} }
.step-progress__step span{ .step-progress__step span {
font-size: 12px !important; font-size: 12px !important;
} }
.step-progress__step-label, .step-progress__step-label,
.step-progress__step--active .step-progress__step-label, .step-progress__step--active span{ .step-progress__step--active .step-progress__step-label,
.step-progress__step--active span {
font-size: 12px !important; font-size: 12px !important;
} }
.page-scroll{ .page-scroll {
height: calc(100vh - 65px); height: calc(100vh - 65px);
overflow-y: scroll; overflow-y: scroll;
} }
.list-scroll{ .list-scroll {
height: calc(100vh - 400px); height: calc(100vh - 400px);
overflow-y: scroll; overflow-y: scroll;
} }
.myNFT-list-scroll{ .myNFT-list-scroll {
height: calc(100vh - 290px); height: calc(100vh - 290px);
overflow-y: scroll; overflow-y: scroll;
} }
.collection-list{ .collection-list {
height: calc(100vh - 60px); height: calc(100vh - 60px);
overflow-y: scroll; overflow-y: scroll;
} }
.van-dialog {
background-color: #1d2649;
.van-dialog{
background-color: #1D2649;
font-size: 14px; font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC; font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400; font-weight: 400;
color: #8899B3; color: #8899b3;
.van-dialog__content,.van-dialog__message, .van-dialog__message--has-title{ .van-dialog__content,
.van-dialog__message,
.van-dialog__message--has-title {
font-size: 14px; font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC; font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400; font-weight: 400;
color: #EEF1F6; color: #eef1f6;
} }
.van-hairline--top, .van-dialog__footer, .van-button{ .van-hairline--top,
background-color: #1D2649; .van-dialog__footer,
.van-button {
background-color: #1d2649;
} }
.van-button__text{ .van-button__text {
font-size: 14px; font-size: 14px;
font-family: PingFangSC-Medium, PingFang SC; font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500; font-weight: 500;
color: #0078FF; color: #0078ff;
}
} }
}
.van-popup{ .van-popup {
.van-action-sheet__gap{ .van-action-sheet__gap {
background-color: #131934; background-color: #131934;
} }
.van-action-sheet__item,.van-action-sheet__cancel{ .van-action-sheet__item,
background-color: #1D2649; .van-action-sheet__cancel {
background-color: #1d2649;
font-size: 14px; font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC; font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400; font-weight: 400;
color: #EEF1F6; color: #eef1f6;
} }
.van-action-sheet__cancel:active, .van-action-sheet__item:active{ .van-action-sheet__cancel:active,
.van-action-sheet__item:active {
background-color: #394267; background-color: #394267;
} }
} }
......
<template> <template>
<div class="register"> <div class="register pt-5">
<div class="title text-font-white mt-5 mb-16 text-2xl">{{ title }}</div> <div class="flex justify-between items-center text-base">
<img src="@/assets/img/cmp_logo.png" class="h-12" alt="" />
<div class=" text-font-white header-text">注册/登录</div>
</div>
<div class="title text-font-white mt-10 mb-16 title-text">{{ title }}</div>
<PhoneInput <PhoneInput
:placeholder="phoneConfig.placeholder" :placeholder="phoneConfig.placeholder"
:maxlength="phoneConfig.maxLen" :maxlength="phoneConfig.maxLen"
...@@ -367,3 +371,17 @@ export default Vue.extend({ ...@@ -367,3 +371,17 @@ export default Vue.extend({
}, },
}); });
</script> </script>
<style scoped>
.header-text{
font-size: 16px;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #EEF1F6;
}
.title-text{
font-size: 30px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #EEF1F6;
}
</style>
\ No newline at end of file
...@@ -145,6 +145,7 @@ ...@@ -145,6 +145,7 @@
key="count" key="count"
text="数量" text="数量"
:value="1" :value="1"
:disabled="true"
type="input-num" type="input-num"
class="text-font-white my-3" class="text-font-white my-3"
@cellOnChange=" @cellOnChange="
...@@ -175,6 +176,7 @@ ...@@ -175,6 +176,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { iSaveData } from "@/service/nftService/types";
import { Dialog } from "vant"; import { Dialog } from "vant";
import Vue from "vue"; import Vue from "vue";
import { mapMutations, mapState } from "vuex"; import { mapMutations, mapState } from "vuex";
...@@ -247,11 +249,12 @@ export default Vue.extend({ ...@@ -247,11 +249,12 @@ export default Vue.extend({
}), }),
validation(): boolean { validation(): boolean {
let disabled = true; let disabled = true;
const { value_name, value_publisher } = this.createNFT; const { value_name, value_publisher, value_des } = this.createNFT;
if (this.currentStep === 1) { if (this.currentStep === 1) {
if ( if (
value_name && value_name &&
value_publisher && value_publisher &&
value_des &&
this.$store.state.create.pickedList.length !== 0 this.$store.state.create.pickedList.length !== 0
) { ) {
disabled = false; disabled = false;
...@@ -313,23 +316,60 @@ export default Vue.extend({ ...@@ -313,23 +316,60 @@ export default Vue.extend({
what(item: Function) { what(item: Function) {
item(this.$router.push("/Nft/create/pick")); item(this.$router.push("/Nft/create/pick"));
}, },
async currentStepChange(val: number) { async publishNft() {
if (this.currentStep === 2 && val === 1) { /* 加密上链的下一步点击回调 */
this.loading3 = true;
try {
await this.$service.nftService.publish({
fileHash: this.fileHash,
id: this.publish.id,
wallet: this.publish.wallet,
nftId: this.publish.nftId,
});
this.$router.back();
} catch (err) {
console.log(err);
}
this.loading3 = false;
},
async uploadFileToOss(file: File): Promise<string> {
const ossRet = (await this.$service.nftService.ossPolicy()) as any;
await this.$service.nftService.uploadFileToOss(file, ossRet);
const { dir, host } = ossRet;
return `${host}/${dir}/${file.name}`;
},
async encryptAndPushToChain() {
this.loading2 = true; this.loading2 = true;
let mistake = false; let mistake = false;
try { try {
let data = {
author: this.createNFT.value_publisher,
categoryId: 1,
name: this.createNFT.value_name,
synopsis: this.createNFT.value_des,
theme: this.pickedList.map((i: any) => i.text as string).toString(),
} as iSaveData;
if (this.createNFT.archives === 0) {
data = {
...data,
fileHash: this.fileHash,
isArchives: this.createNFT.archives,
};
} else if (this.createNFT.archives === 1) {
const fileUrl = await this.uploadFileToOss(this.file);
data = {
...data,
isArchives: this.createNFT.archives,
fileHash: this.fileHash,
fileUrl: fileUrl,
fileName: this.file.name,
isGrant: this.createNFT.grant,
};
}
const { id, nftId, wallet, fileHash } = const { id, nftId, wallet, fileHash } =
await this.$service.nftService.save( await this.$service.nftService.save(data);
this.createNFT.value_publisher,
1,
this.fileHash,
this.createNFT.archives,
this.createNFT.value_name,
this.createNFT.value_des,
this.pickedList.map((i: any) => i.text as string).toString(),
this.file,
this.createNFT.grant
);
this.publish.fileHash = fileHash; this.publish.fileHash = fileHash;
this.publish.nftId = nftId; this.publish.nftId = nftId;
this.publish.id = id; this.publish.id = id;
...@@ -339,20 +379,12 @@ export default Vue.extend({ ...@@ -339,20 +379,12 @@ export default Vue.extend({
} }
this.loading2 = false; this.loading2 = false;
if (mistake) return; if (mistake) return;
},
async currentStepChange(val: number) {
if (this.currentStep === 2 && val === 1) {
await this.encryptAndPushToChain();
} else if (this.currentStep === 3 && val === 1) { } else if (this.currentStep === 3 && val === 1) {
this.loading3 = true; await this.publishNft();
try {
await this.$service.nftService.publish({
fileHash: this.fileHash,
id: this.publish.id,
wallet: this.publish.wallet,
nftId: this.publish.nftId,
});
this.$router.back();
} catch (err) {
console.log(err);
}
this.loading3 = false;
} }
if (this.currentStep < this.mySteps.length + 1) { if (this.currentStep < this.mySteps.length + 1) {
this.currentStep += val; this.currentStep += val;
......
...@@ -78,6 +78,7 @@ ...@@ -78,6 +78,7 @@
import Vue from "vue"; import Vue from "vue";
import { Uploader, Loading } from "vant"; import { Uploader, Loading } from "vant";
import { mapMutations, mapState } from "vuex"; import { mapMutations, mapState } from "vuex";
import md5 from "md5";
enum uploadStatus { enum uploadStatus {
NULL, NULL,
...@@ -120,15 +121,22 @@ export default Vue.extend({ ...@@ -120,15 +121,22 @@ export default Vue.extend({
}), }),
async afterRead(file: File) { async afterRead(file: File) {
try { try {
const ab = await file.arrayBuffer();
const fileMd5 = md5(Buffer.from(ab));
this.status = uploadStatus.uploading; this.status = uploadStatus.uploading;
const ret = await this.$service.nftService.getMd5(file); // const ossRet = await this.$service.nftService.ossPolicy();
// const uploadRet = await this.$service.nftService.uploadFileToOss(
// file,
// ossRet
// );
this.setState({ this.setState({
fileName: file.name, fileName: file.name,
fileHash: ret, fileHash: fileMd5,
file: file, file: file,
}); });
this.status = uploadStatus.success; this.status = uploadStatus.success;
} catch (err) { } catch (err) {
console.log(err, "show err");
this.status = uploadStatus.failed; this.status = uploadStatus.failed;
} }
}, },
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
loading.... loading....
</div> --> </div> -->
<div class="w-11/12 mx-auto mt-6 text-font-white"> <div class="w-11/12 mx-auto mt-6 text-font-white">
<SkeletonNftDetail v-if="false"/>
<app-collectionCard :colletionData='nftData'></app-collectionCard> <app-collectionCard :colletionData='nftData'></app-collectionCard>
<div class="app-icons mx-auto grid grid-cols-4 my-6" v-if="isOwner"> <div class="app-icons mx-auto grid grid-cols-4 my-6" v-if="isOwner">
<div <div
...@@ -127,6 +128,7 @@ ...@@ -127,6 +128,7 @@
<script lang="ts"> <script lang="ts">
import Vue from "vue"; import Vue from "vue";
import SkeletonNftDetail from "@/components/common/Skeleton/SkeletonNftDetail.vue"
const apps = [ const apps = [
{ {
text: "版权认证", text: "版权认证",
...@@ -173,6 +175,7 @@ export default Vue.extend({ ...@@ -173,6 +175,7 @@ export default Vue.extend({
'app-btn':()=>import('@/components/common/Btn.vue'), 'app-btn':()=>import('@/components/common/Btn.vue'),
// 'app-scrollbar':()=>import('@/components/common/ScrollBar.vue'), // 'app-scrollbar':()=>import('@/components/common/ScrollBar.vue'),
"app-collectionCard": () => import("@/components/CollectionCard.vue"), "app-collectionCard": () => import("@/components/CollectionCard.vue"),
SkeletonNftDetail,
}, },
methods:{ methods:{
async setMyCollection():Promise<void>{ async setMyCollection():Promise<void>{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment