nieyuge 2 rokov pred
rodič
commit
46041c66d9

+ 13 - 0
package-lock.json

@@ -314,6 +314,11 @@
         "delayed-stream": "~1.0.0"
       }
     },
+    "commander": {
+      "version": "9.4.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz",
+      "integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw=="
+    },
     "compressible": {
       "version": "2.0.18",
       "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
@@ -975,6 +980,14 @@
         "mime-db": "1.52.0"
       }
     },
+    "mockjs": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/mockjs/-/mockjs-1.1.0.tgz",
+      "integrity": "sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==",
+      "requires": {
+        "commander": "*"
+      }
+    },
     "ms": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",

+ 1 - 0
package.json

@@ -18,6 +18,7 @@
     "axios": "^0.27.2",
     "element-plus": "^2.2.9",
     "js-cookie": "^3.0.1",
+    "mockjs": "^1.1.0",
     "vue": "^3.2.25",
     "vue-router": "^4.0.15"
   },

+ 0 - 2
src/components/footer.vue

@@ -27,8 +27,6 @@
 </template>
 
 <script lang="ts" setup>
-import { postRequest } from '../static/http'
-
 const twitter = ()  => {
     window.open(`https://twitter.com/denet2022`);
 }

+ 1 - 11
src/components/header.vue

@@ -17,7 +17,7 @@
 <script lang="ts" setup>
 import Api from '../static/http/api'
 import { postRequest } from '../static/http'
-import { getMid, appVersionCode, getOauthUrl, createWindow, callBackUrl } from '../static/utils'
+import { getOauthUrl, createWindow, callBackUrl } from '../static/utils'
 import { getStorage, removeStorage, setStorage, storageKey } from '../static/utils/storage'
 import { ref } from 'vue'
 import { ElMessage } from 'element-plus'
@@ -55,10 +55,6 @@ const login = () => {
 
 const twitterAuth = () => {
     postRequest(Api.twitterRequestToken, {
-        baseInfo: {
-            mid: getMid(),
-            appVersionCode,
-        },
         params: {
             oauthCallback: callBackUrl
         }
@@ -75,7 +71,6 @@ const twitterAuth = () => {
             }, 500)
         } else {
             ElMessage({
-                offset: 100,
                 type: 'error',
                 message: msg,
             })
@@ -87,10 +82,6 @@ const twitterLogin = (data: { authToken: string, consumerKey: string }) => {
     let verifier = getStorage(storageKey.verifier)
     if (verifier) {
         postRequest(Api.twitterLogin,  {
-            baseInfo: {
-                mid: getMid(),
-                appVersionCode,
-            },
             params: {
                 consumerKey: data.consumerKey,
                 oauthToken: data.authToken,
@@ -104,7 +95,6 @@ const twitterLogin = (data: { authToken: string, consumerKey: string }) => {
                 location.href = `/nft/list`
             } else {
                 ElMessage({
-                    offset: 100,
                     type: 'error',
                     message: msg,
                 })

+ 1 - 1
src/pages/index.vue

@@ -72,7 +72,7 @@
 
 <script setup lang="ts">
 import { onMounted } from 'vue';
-import { useRoute, useRouter } from 'vue-router'
+import { useRoute } from 'vue-router'
 import { setStorage, storageKey } from '../static/utils/storage'
 import headerLayer from '../components/header.vue';
 import footerLayer from '../components/footer.vue';

+ 170 - 20
src/pages/nft/list.vue

@@ -9,21 +9,33 @@
                 <div class="logout" @click="logout">Sign out</div>
             </div>
             <div class="list">
-                <div class="item">
-                    <div class="logo">
-                        <img src="" alt="" />
+                <template v-if="pageList.length">
+                    <div class="item" v-for="(item, index) in pageList" :key="index">
+                        <div class="logo">
+                            <img :src="item.nftCardFaceImage" alt="" />
+                        </div>
+                        <div class="desc">
+                            <div class="name">{{item.nftProjectName}}</div>
+                            <div class="font">Sell <span>{{item.sellCount}}/{{item.totalCount}}</span></div>
+                            <div class="font">Earnings <span>{{item.earningAmount}} {{item.currencySymbol}}</span></div>
+                        </div>
+                        <div class="opt">
+                            <template v-if="item.publishStatus === 1">
+                                <el-button link type="danger" @click="unpublish(item)">Unpublish</el-button>
+                                <el-button link type="primary" @click="view">View</el-button>
+                            </template>
+                            <template v-else>
+                                <el-button link type="danger" @click="remove(item)">Delete</el-button>
+                                <el-button link type="primary" @click="publish(item)">Publish</el-button>
+                            </template>
+                        </div>
                     </div>
-                    <div class="desc">
-                        <div class="name">LegalDAO Members</div>
-                        <div class="font">Sell <span>175/1000</span></div>
-                        <div class="font">Earnings <span>107.5 USDT</span></div>
+                </template>
+                <template v-else>
+                    <div class="empty">
+                        <img src="../../static/img/icon-empty.svg" alt="" />
                     </div>
-                    <div class="opt">
-                        <el-button link type="danger">Delete</el-button>
-                        <el-button link type="primary">Publish</el-button>
-                    </div>
-                </div>
-                <!-- <el-empty description="description" /> -->
+                </template>
             </div>
             <div class="add" @click="add">
                 <img src="../../static/img/header-add.svg" alt="">
@@ -34,10 +46,13 @@
 
     <!-- publish -->
     <div class="publish" v-if="publishDialog">
-        <div class="msg">Irrevocable after publish</div>
+        <div class="msg">
+            <template v-if="publishType === 1">Irrevocable after publish</template>
+            <template v-else>Do you wish to unlist the NFT collection</template>
+        </div>
         <div class="buttons">
-            <button>Cancel</button>
-            <button class="confirm">Continue</button>
+            <button @click="hidePublishLayer">Cancel</button>
+            <button class="confirm" @click="confirmPublishLayer">Continue</button>
         </div>
     </div>
     <div class="bg" v-if="publishDialog"></div>
@@ -46,22 +61,33 @@
     <div class="publish delete" v-if="deleteDialog">
         <div class="msg">Once deleted, it cannot be restored</div>
         <div class="buttons">
-            <button>Cancel</button>
-            <button class="confirm">Continue</button>
+            <button @click="hideDeleteLayer">Cancel</button>
+            <button class="confirm" @click="confirmDeleteLayer">Continue</button>
         </div>
     </div>
     <div class="bg" v-if="deleteDialog"></div>
-
 </template>
 
 <script lang="ts" setup>
 import { onMounted, ref } from 'vue'
+import { ElMessage } from 'element-plus'
+import Api from '../../static/http/api';
+import { postRequest } from '../../static/http'
 import { getStorage, storageKey, removeStorage } from '../../static/utils/storage'
 
-const userInfo: any = ref({});
+const userInfo: any = ref({})
+
+const publishType = ref(0)
+const publishItem = ref(null)
 const publishDialog = ref(false)
+
+const deleteItem = ref(null)
 const deleteDialog = ref(false)
 
+const pageNum = ref(1)
+const pageSize = 1000
+const pageList = ref([])
+
 const logout = () => {
     removeStorage(storageKey.userInfo)
     location.href = `/`
@@ -71,8 +97,125 @@ const add = () => {
     location.href = `/nft/add`
 }
 
+const remove = (item: any) => {
+    deleteItem.value = JSON.parse(JSON.stringify(item));
+    showDeleteLayer()
+}
+
+const publish = (item: any) => {
+    publishType.value = 1;
+    publishItem.value = item;
+    showPublishLayer()
+}
+
+const unpublish = (item: any) => {
+    publishType.value = 2;
+    publishItem.value = item;
+    showPublishLayer()
+}
+
+const view = () => {
+    let userInfo = getStorage(storageKey.userInfo);
+    let nickName = userInfo && userInfo.nickName || '';
+    // open
+    window.open(`https://twitter.com/${nickName}`);
+}
+
+const getList = () => {
+    postRequest(Api.userNftList, {
+        params: {
+            pageNum: pageNum.value,
+            pageSize: pageSize
+        }
+    }).then(res => {
+        let { code, data } = res;
+        if (code === 0) {
+            pageList.value = data;
+        }
+    })
+}
+
+const hideDeleteLayer = () => {
+    deleteDialog.value = false;
+}
+
+const showDeleteLayer = () => {
+    deleteDialog.value = true;
+}
+
+const confirmDeleteLayer = () => {
+    postRequest(Api.userNftDel, {
+        params: {
+            nftProjectId: deleteItem.value.nftProjectId,
+        }
+    }).then(res => {
+        let { code, msg } = res;
+        if ( code === 0 ) {
+            // filter
+            pageList.value.some((item, index) => {
+                if (item.nftProjectId === deleteItem.value.nftProjectId) {
+                    pageList.value.splice(index, 1);
+                    return true;
+                }
+            })
+            ElMessage({
+                type: 'success',
+                message: 'Delete Success!',
+            })
+        } else {
+            ElMessage({
+                type: 'error',
+                message: msg,
+            })
+        }
+        hideDeleteLayer()
+    })
+}
+
+const hidePublishLayer = () => {
+    publishDialog.value = false;
+}
+
+const showPublishLayer = () => {
+    publishDialog.value = true;
+}
+
+const confirmPublishLayer = () => {
+    let item = JSON.parse(JSON.stringify(publishItem.value));
+    let status = publishType.value === 1 ? 1 : 0;
+    // request
+    postRequest(Api.userNftSetStatus, {
+        params: {
+            nftProjectId : item.nftProjectId,
+            publishStatus : status
+        }
+    }).then(res => {
+        let { code, msg } = res;
+        if ( code === 0 ) {
+            pageList.value.some((row) => {
+                if (row.nftProjectId === item.nftProjectId) {
+                    row.publishStatus = status;
+                    return true;
+                }
+            })
+            ElMessage({
+                type: 'success',
+                message: publishType.value === 1 ? 'Published Successfully!' : 'We have listed your NFT collection!',
+            })
+        } else {
+            ElMessage({
+                type: 'error',
+                message: msg
+            })
+        }
+        hidePublishLayer()
+    })
+}
+
 onMounted(() => {
     userInfo.value = getStorage(storageKey.userInfo);
+    // 获取列表
+    getList()
 })
 </script>
 
@@ -122,6 +265,12 @@ onMounted(() => {
         margin: 20px;
         height: 360px;
         overflow-y: auto;
+        .empty {
+            position: absolute;
+            top: 50%;
+            left: 50%;
+            transform: translate(-50%, -50%);
+        }
         .item {
             display: flex;
             align-items: center;
@@ -133,6 +282,7 @@ onMounted(() => {
                 margin-bottom: unset;
             }
             .logo {
+                overflow: hidden;
                 width: 70px;
                 height: 70px;
                 margin: 0 24px;

+ 4 - 0
src/static/http/api.ts

@@ -1,4 +1,8 @@
 export default {
     'twitterLogin' : '/denet/user/twitterLogin',
     'twitterRequestToken' : '/denet/user/twitterRequestToken',
+    'userNftAdd' : '/denet/nft/project/create/new',
+    'userNftDel' : '/denet/nft/project/create/delete',
+    'userNftList' : '/denet/nft/project/create/list',
+    'userNftSetStatus' : '/denet/nft/project/create/setPublishStatus',
 }

+ 12 - 2
src/static/http/index.ts

@@ -1,6 +1,8 @@
 // http封装库
-import { getEnvConfig } from '../utils';
 import axios from 'axios';
+import { getEnvConfig, getMid, getUserInfo, appVersionCode, } from '../utils';
+// 测试数据(需手动开启关闭)
+import '../mockjs/index';
 
 // axios config
 const { host } = getEnvConfig();
@@ -22,10 +24,18 @@ instance.interceptors.response.use((res) => {
 
 export const postRequest = (url: string, params = {}, config = null) => {
     const myConfig = {};
+    const userInfo = getUserInfo();
     if (config) {
         Object.assign(myConfig, config);
     }
-    params = Object.assign({}, params);
+    params = Object.assign({
+        baseInfo: {
+            mid: getMid(),
+            loginUid: userInfo && userInfo.uid || '',
+            token: userInfo && userInfo.accessToken || '',
+            appVersionCode,
+        },
+    }, params);
 
     return instance.post(url, params, myConfig).then(res => {
         return res;

+ 13 - 0
src/static/mockjs/index.ts

@@ -0,0 +1,13 @@
+// @ts-ignore
+import mockJs from 'mockjs';
+import Api from '../http/api';
+import { getEnvConfig } from '../utils';
+import { userNftList, userNftDel, userNftSetStatus } from './nft-data';
+
+// const
+const { host } = getEnvConfig();
+
+// mock
+mockJs.mock(host + Api.userNftList, 'post', userNftList);
+mockJs.mock(host + Api.userNftDel, 'post', userNftDel);
+mockJs.mock(host + Api.userNftSetStatus, 'post', userNftSetStatus);

+ 24 - 0
src/static/mockjs/nft-data.ts

@@ -0,0 +1,24 @@
+export const userNftList = {
+    'code' : 0,
+    'msg' : '',
+    'data|20' : [{
+        "currencySymbol" : "@character('$¥€')",
+        "earningAmount" : "@integer(2000, 5000)",
+        "nftCardFaceImage" : "@image('70x70')",
+        "nftProjectId" : "@integer(20000, 500000000000)",
+        "nftProjectName" : "@word",
+        "publishStatus|1" : [0, 1],
+        "sellCount" : "@integer(1, 5000)",
+        "totalCount" : 5000
+    }]
+};
+
+export const userNftDel = {
+    'code|1' : [0, 1],
+    "msg": "@word"
+}
+
+export const userNftSetStatus = {
+    'code|1' : [0, 1],
+    "msg": "@word"
+}

+ 10 - 0
src/static/utils/index.ts

@@ -1,5 +1,6 @@
 // @ts-ignore
 import Cookie from 'js-cookie';
+import { getStorage, storageKey } from './storage'
 
 export const appVersionCode = 12;
 export const appType = 1;
@@ -41,6 +42,15 @@ export const getMid = () => {
     return _mid;
 }
 
+export const getUserInfo = () => {
+    let userInfo = getStorage(storageKey.userInfo) || null;
+    if (userInfo) {
+        return userInfo;
+    } else {
+        return null
+    }
+}
+
 // 推特授权url
 export const getOauthUrl = (token: string) => {
     return `https://api.twitter.com/oauth/authenticate?oauth_token=${token}`