Browse Source

Merge branch 'master' of http://git.izouma.com/xiongzhu/9th

panhui 4 years ago
parent
commit
6c6cb70443

+ 3 - 0
src/main/java/com/izouma/nineth/domain/Asset.java

@@ -52,6 +52,9 @@ public class Asset extends BaseEntity {
     @ApiModelProperty("特性")
     @ApiModelProperty("特性")
     private List<Collection.CollectionProperty> properties;
     private List<Collection.CollectionProperty> properties;
 
 
+    @ApiModelProperty("分类")
+    private String category;
+
     @ApiModelProperty("是否可转售")
     @ApiModelProperty("是否可转售")
     private boolean canResale;
     private boolean canResale;
 
 

+ 17 - 14
src/main/java/com/izouma/nineth/domain/Collection.java

@@ -65,6 +65,23 @@ public class Collection extends BaseEntity {
     @Enumerated(EnumType.STRING)
     @Enumerated(EnumType.STRING)
     private CollectionType type;
     private CollectionType type;
 
 
+    @Column(columnDefinition = "TEXT")
+    @Convert(converter = PropertyListConverter.class)
+    @ApiModelProperty("特性")
+    private List<CollectionProperty> properties;
+
+    @ApiModelProperty("是否可转售")
+    private boolean canResale;
+
+    @ApiModelProperty("版税比例")
+    private int royalties;
+
+    @ApiModelProperty("手续费比例")
+    private int serviceCharge;
+
+    @ApiModelProperty("分类")
+    private String category;
+
     @ApiModelProperty("来源")
     @ApiModelProperty("来源")
     @Enumerated(EnumType.STRING)
     @Enumerated(EnumType.STRING)
     private CollectionSource source;
     private CollectionSource source;
@@ -91,20 +108,6 @@ public class Collection extends BaseEntity {
     @Column(precision = 10, scale = 2)
     @Column(precision = 10, scale = 2)
     private BigDecimal price;
     private BigDecimal price;
 
 
-    @Column(columnDefinition = "TEXT")
-    @Convert(converter = PropertyListConverter.class)
-    @ApiModelProperty("特性")
-    private List<CollectionProperty> properties;
-
-    @ApiModelProperty("是否可转售")
-    private boolean canResale;
-
-    @ApiModelProperty("版税比例")
-    private int royalties;
-
-    @ApiModelProperty("手续费比例")
-    private int serviceCharge;
-
     @ApiModelProperty("盲盒开售时间")
     @ApiModelProperty("盲盒开售时间")
     private LocalDateTime startTime;
     private LocalDateTime startTime;
 
 

+ 3 - 0
src/main/java/com/izouma/nineth/domain/Order.java

@@ -56,6 +56,9 @@ public class Order extends BaseEntity {
     @ApiModelProperty("特性")
     @ApiModelProperty("特性")
     private List<Collection.CollectionProperty> properties;
     private List<Collection.CollectionProperty> properties;
 
 
+    @ApiModelProperty("分类")
+    private String category;
+
     @ApiModelProperty("是否可转售")
     @ApiModelProperty("是否可转售")
     private boolean canResale;
     private boolean canResale;
 
 

+ 3 - 0
src/main/java/com/izouma/nineth/repo/AssetRepo.java

@@ -1,6 +1,7 @@
 package com.izouma.nineth.repo;
 package com.izouma.nineth.repo;
 
 
 import com.izouma.nineth.domain.Asset;
 import com.izouma.nineth.domain.Asset;
+import com.izouma.nineth.enums.AssetStatus;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Modifying;
@@ -13,4 +14,6 @@ public interface AssetRepo extends JpaRepository<Asset, Long>, JpaSpecificationE
     @Modifying
     @Modifying
     @Transactional
     @Transactional
     void softDelete(Long id);
     void softDelete(Long id);
+
+    long countByIpfsUrlAndStatusNot(String ipfsUrl, AssetStatus status);
 }
 }

+ 6 - 1
src/main/java/com/izouma/nineth/service/AssetService.java

@@ -56,10 +56,12 @@ public class AssetService {
         }
         }
         try {
         try {
             NFT nft = nftService.createToken(user.getNftAccount());
             NFT nft = nftService.createToken(user.getNftAccount());
+            String ipfsUrl = ipfsUpload(order.getPic().get(0));
             if (nft != null) {
             if (nft != null) {
                 Asset asset = Asset.builder()
                 Asset asset = Asset.builder()
                         .userId(user.getId())
                         .userId(user.getId())
                         .orderId(order.getId())
                         .orderId(order.getId())
+                        .collectionId(order.getCollectionId())
                         .minter(order.getMinter())
                         .minter(order.getMinter())
                         .minterId(order.getMinterId())
                         .minterId(order.getMinterId())
                         .minterAvatar(order.getMinterAvatar())
                         .minterAvatar(order.getMinterAvatar())
@@ -67,6 +69,7 @@ public class AssetService {
                         .detail(order.getDetail())
                         .detail(order.getDetail())
                         .pic(order.getPic())
                         .pic(order.getPic())
                         .properties(order.getProperties())
                         .properties(order.getProperties())
+                        .category(order.getCategory())
                         .canResale(order.isCanResale())
                         .canResale(order.isCanResale())
                         .royalties(order.getRoyalties())
                         .royalties(order.getRoyalties())
                         .serviceCharge(order.getServiceCharge())
                         .serviceCharge(order.getServiceCharge())
@@ -76,7 +79,8 @@ public class AssetService {
                         .gasUsed(nft.getGasUsed())
                         .gasUsed(nft.getGasUsed())
                         .price(order.getPrice())
                         .price(order.getPrice())
                         .status(AssetStatus.NORMAL)
                         .status(AssetStatus.NORMAL)
-                        .ipfsUrl(ipfsUpload(order.getPic().get(0)))
+                        .ipfsUrl(ipfsUrl)
+                        .number((int) (assetRepo.countByIpfsUrlAndStatusNot(ipfsUrl, AssetStatus.TRANSFERRED) + 1))
                         .build();
                         .build();
                 assetRepo.save(asset);
                 assetRepo.save(asset);
                 applicationContext.publishEvent(new CreateAssetEvent(this, true, order, asset));
                 applicationContext.publishEvent(new CreateAssetEvent(this, true, order, asset));
@@ -104,6 +108,7 @@ public class AssetService {
                 Asset asset = Asset.builder()
                 Asset asset = Asset.builder()
                         .userId(user.getId())
                         .userId(user.getId())
                         .orderId(order.getId())
                         .orderId(order.getId())
+                        .collectionId(order.getCollectionId())
                         .minter(winItem.getMinter())
                         .minter(winItem.getMinter())
                         .minterId(winItem.getMinterId())
                         .minterId(winItem.getMinterId())
                         .minterAvatar(winItem.getMinterAvatar())
                         .minterAvatar(winItem.getMinterAvatar())

+ 1 - 0
src/main/java/com/izouma/nineth/service/OrderService.java

@@ -101,6 +101,7 @@ public class OrderService {
                 .pic(collection.getPics())
                 .pic(collection.getPics())
                 .detail(collection.getDetail())
                 .detail(collection.getDetail())
                 .properties(collection.getProperties())
                 .properties(collection.getProperties())
+                .category(collection.getCategory())
                 .canResale(collection.isCanResale())
                 .canResale(collection.isCanResale())
                 .royalties(collection.getRoyalties())
                 .royalties(collection.getRoyalties())
                 .serviceCharge(collection.getServiceCharge())
                 .serviceCharge(collection.getServiceCharge())

+ 1 - 1
src/main/nine-space/src/views/asset/Detail.vue

@@ -26,7 +26,7 @@
       </div>
       </div>
       <div class="title">{{ info.name }}</div>
       <div class="title">{{ info.name }}</div>
       <div class="info-bottom">
       <div class="info-bottom">
-        <span class="text1"> 编号 {{ info.number }} </span>
+        <span class="text1" v-if="info.number"> 编号 {{ info.number }} </span>
         <!-- <van-button
         <!-- <van-button
           type="primary"
           type="primary"
           plain
           plain

+ 3 - 3
src/main/resources/application.yaml

@@ -64,7 +64,7 @@ wx:
     msg_format: JSON
     msg_format: JSON
   pay:
   pay:
     app-id: wx2375cba2eec2c479
     app-id: wx2375cba2eec2c479
-    mch-id: 1529090291
+    mch-id: 1614898941
     mch-key: A2qWTQzN5EkvgeWgmnnTSY4vV3Y6Xxbj
     mch-key: A2qWTQzN5EkvgeWgmnnTSY4vV3Y6Xxbj
     sub-app-id:
     sub-app-id:
     sub-mch-id:
     sub-mch-id:
@@ -117,7 +117,7 @@ alipay:
   app-cert-path: classpath:cert/appCertPublicKey_2021002120645023.crt
   app-cert-path: classpath:cert/appCertPublicKey_2021002120645023.crt
   root-cert-path: classpath:cert/alipayRootCert.crt
   root-cert-path: classpath:cert/alipayRootCert.crt
   notify-url: https://nft.9space.vip/notify/order/alipay
   notify-url: https://nft.9space.vip/notify/order/alipay
-  return-url: https://nft.9space.vip/9th/orders
+  return-url: https://nft.9space.vip/9th/home
 ---
 ---
 
 
 spring:
 spring:
@@ -138,4 +138,4 @@ wx:
     return-url: https://nft.9space.vip/9th/orders
     return-url: https://nft.9space.vip/9th/orders
 alipay:
 alipay:
   notify-url: https://nft.9space.vip/notify/order/alipay
   notify-url: https://nft.9space.vip/notify/order/alipay
-  return-url: https://nft.9space.vip/9th/orders
+  return-url: https://nft.9space.vip/9th/home

+ 9 - 5
src/main/vue/src/router.js

@@ -23,13 +23,17 @@ const router = new Router({
                     name: '404',
                     name: '404',
                     component: () => import(/* webpackChunkName: "404" */ '@/views/404.vue')
                     component: () => import(/* webpackChunkName: "404" */ '@/views/404.vue')
                 },
                 },
+                // {
+                //     path: '/dashboard',
+                //     name: 'dashboard',
+                //     component: () => import(/* webpackChunkName: "404" */ '@/views/Dashboard.vue'),
+                //     meta: {
+                //         title: '首页'
+                //     }
+                // },
                 {
                 {
                     path: '/dashboard',
                     path: '/dashboard',
-                    name: 'dashboard',
-                    component: () => import(/* webpackChunkName: "404" */ '@/views/Dashboard.vue'),
-                    meta: {
-                        title: '首页'
-                    }
+                    redirect: 'collectionList'
                 },
                 },
                 {
                 {
                     path: '/api',
                     path: '/api',

+ 2 - 4
src/main/vue/src/views/Admin.vue

@@ -1,10 +1,8 @@
 <template>
 <template>
     <el-container id="app">
     <el-container id="app">
         <el-aside :width="collapse ? '65px' : '200px'" class="aside">
         <el-aside :width="collapse ? '65px' : '200px'" class="aside">
-            <div v-if="collapse" class="logo-wrapper collapse" @click="$router.push('/dashboard')">
-                Thoma<br /><b>Admin</b>
-            </div>
-            <div v-else class="logo-wrapper" @click="$router.push('/dashboard')">9th</div>
+            <div v-if="collapse" class="logo-wrapper collapse" @click="$router.push('/dashboard')"></div>
+            <div v-else class="logo-wrapper" @click="$router.push('/dashboard')">第九空间</div>
             <el-menu
             <el-menu
                 :collapse="collapse"
                 :collapse="collapse"
                 :background-color="$theme['menu-bg']"
                 :background-color="$theme['menu-bg']"

+ 28 - 4
src/main/vue/src/views/BlindBoxEdit.vue

@@ -25,6 +25,11 @@
                     <el-form-item prop="minterId" label="创建者">
                     <el-form-item prop="minterId" label="创建者">
                         <minter-select v-model="formData.minterId" @detail="onMinterDetail"></minter-select>
                         <minter-select v-model="formData.minterId" @detail="onMinterDetail"></minter-select>
                     </el-form-item>
                     </el-form-item>
+                    <el-form-item prop="category" label="分类">
+                        <el-select v-model="formData.category">
+                            <el-option v-for="item in cateogories" :label="item" :value="item" :key="item"></el-option>
+                        </el-select>
+                    </el-form-item>
                     <el-form-item prop="detail" label="详情" style="width: calc(100vw - 450px)">
                     <el-form-item prop="detail" label="详情" style="width: calc(100vw - 450px)">
                         <rich-text v-model="formData.detail"></rich-text>
                         <rich-text v-model="formData.detail"></rich-text>
                     </el-form-item>
                     </el-form-item>
@@ -80,7 +85,7 @@
                     <el-form-item prop="total" label="发行数量">
                     <el-form-item prop="total" label="发行数量">
                         <el-input-number v-model="formData.total" disabled></el-input-number>
                         <el-input-number v-model="formData.total" disabled></el-input-number>
                     </el-form-item>
                     </el-form-item>
-                    <el-form-item prop="collectionIds" label="包含作品" style="width: calc(100vw - 450px)">
+                    <el-form-item prop="items" label="包含作品" style="width: calc(100vw - 450px)">
                         <el-table :data="blindBoxItems">
                         <el-table :data="blindBoxItems">
                             <el-table-column
                             <el-table-column
                                 prop="collectionId"
                                 prop="collectionId"
@@ -114,8 +119,13 @@
                     <el-form-item prop="salable" label="可售">
                     <el-form-item prop="salable" label="可售">
                         <el-switch v-model="formData.salable" active-text="可销售" inactive-text="仅展示"></el-switch>
                         <el-switch v-model="formData.salable" active-text="可销售" inactive-text="仅展示"></el-switch>
                     </el-form-item>
                     </el-form-item>
+                    <el-form-item prop="startTime" label="开售时间">
+                        <el-date-picker type="datetime" value-format="yyyy-MM-dd HH:mm:ss"></el-date-picker>
+                    </el-form-item>
                     <el-form-item class="form-submit">
                     <el-form-item class="form-submit">
-                        <el-button @click="onSave" :loading="saving" type="primary" v-if="!formData.id"> 保存 </el-button>
+                        <el-button @click="onSave" :loading="saving" type="primary" v-if="!formData.id">
+                            保存
+                        </el-button>
                         <!-- <el-button @click="onDelete" :disabled="saving" type="danger" v-if="formData.id">
                         <!-- <el-button @click="onDelete" :disabled="saving" type="danger" v-if="formData.id">
                             删除
                             删除
                         </el-button> -->
                         </el-button> -->
@@ -329,7 +339,20 @@ export default {
                         },
                         },
                         trigger: 'blur'
                         trigger: 'blur'
                     }
                     }
-                ]
+                ],
+                startTime: [{ required: true, message: '请填写开售时间' }],
+                items: [
+                    {
+                        validator: (rule, value, callback) => {
+                            if (this.blindBoxItems.length === 0) {
+                                callback(new Error('请添加盲盒内容'));
+                                return;
+                            }
+                            callback();
+                        }
+                    }
+                ],
+                category: [{ required: true, message: '请填写分类' }]
             },
             },
             typeOptions: [
             typeOptions: [
                 { label: '默认', value: 'DEFAULT' },
                 { label: '默认', value: 'DEFAULT' },
@@ -348,7 +371,8 @@ export default {
             addItemFormRules: {
             addItemFormRules: {
                 id: [{ required: true, message: '请选择作品' }],
                 id: [{ required: true, message: '请选择作品' }],
                 total: [{ required: true, message: '请输入数量' }]
                 total: [{ required: true, message: '请输入数量' }]
-            }
+            },
+            cateogories: ['收藏品', '数字艺术', '门票', '游戏', '音乐', '使用', '其他']
         };
         };
     },
     },
     methods: {
     methods: {

+ 9 - 2
src/main/vue/src/views/CollectionEdit.vue

@@ -25,6 +25,11 @@
                     <el-form-item prop="minterId" label="铸造者">
                     <el-form-item prop="minterId" label="铸造者">
                         <minter-select v-model="formData.minterId" @detail="onMinterDetail"></minter-select>
                         <minter-select v-model="formData.minterId" @detail="onMinterDetail"></minter-select>
                     </el-form-item>
                     </el-form-item>
+                    <el-form-item prop="category" label="分类">
+                        <el-select v-model="formData.category">
+                            <el-option v-for="item in cateogories" :label="item" :value="item" :key="item"></el-option>
+                        </el-select>
+                    </el-form-item>
                     <el-form-item prop="detail" label="详情" style="width: calc(100vw - 450px)">
                     <el-form-item prop="detail" label="详情" style="width: calc(100vw - 450px)">
                         <rich-text v-model="formData.detail"></rich-text>
                         <rich-text v-model="formData.detail"></rich-text>
                     </el-form-item>
                     </el-form-item>
@@ -224,7 +229,8 @@ export default {
                         },
                         },
                         trigger: 'blur'
                         trigger: 'blur'
                     }
                     }
-                ]
+                ],
+                category: [{ required: true, message: '请填写分类' }]
             },
             },
             typeOptions: [
             typeOptions: [
                 { label: '默认', value: 'DEFAULT' },
                 { label: '默认', value: 'DEFAULT' },
@@ -235,7 +241,8 @@ export default {
                 { label: '官方', value: 'OFFICIAL' },
                 { label: '官方', value: 'OFFICIAL' },
                 { label: '用户铸造', value: 'USER' },
                 { label: '用户铸造', value: 'USER' },
                 { label: '转让', value: 'TRANSFER' }
                 { label: '转让', value: 'TRANSFER' }
-            ]
+            ],
+            cateogories: ['收藏品', '数字艺术', '门票', '游戏', '音乐', '使用', '其他']
         };
         };
     },
     },
     methods: {
     methods: {

+ 18 - 10
src/main/vue/src/views/OrderList.vue

@@ -1,7 +1,7 @@
 <template>
 <template>
     <div class="list-view">
     <div class="list-view">
         <page-title>
         <page-title>
-            <el-button
+            <!-- <el-button
                 @click="addRow"
                 @click="addRow"
                 type="primary"
                 type="primary"
                 icon="el-icon-plus"
                 icon="el-icon-plus"
@@ -9,7 +9,7 @@
                 class="filter-item"
                 class="filter-item"
             >
             >
                 新增
                 新增
-            </el-button>
+            </el-button> -->
             <el-button
             <el-button
                 @click="download"
                 @click="download"
                 icon="el-icon-upload2"
                 icon="el-icon-upload2"
@@ -21,6 +21,14 @@
             </el-button>
             </el-button>
         </page-title>
         </page-title>
         <div class="filters-container">
         <div class="filters-container">
+            <el-select v-model="status" placeholder="筛选状态" clearable @change="getData">
+                <el-option
+                    v-for="item in statusOptions"
+                    :key="item.value"
+                    :value="item.value"
+                    :label="item.label"
+                ></el-option>
+            </el-select>
             <el-input
             <el-input
                 placeholder="搜索..."
                 placeholder="搜索..."
                 v-model="search"
                 v-model="search"
@@ -46,9 +54,8 @@
             <el-table-column prop="id" label="ID" width="100"> </el-table-column>
             <el-table-column prop="id" label="ID" width="100"> </el-table-column>
             <el-table-column prop="userId" label="用户ID"> </el-table-column>
             <el-table-column prop="userId" label="用户ID"> </el-table-column>
             <el-table-column prop="collectionId" label="藏品ID"> </el-table-column>
             <el-table-column prop="collectionId" label="藏品ID"> </el-table-column>
-            <el-table-column prop="qty" label="数量"> </el-table-column>
-            <el-table-column prop="name" label="名称"> </el-table-column>
-            <el-table-column prop="pic" label="图片">
+            <el-table-column prop="name" label="名称" show-overflow-tooltip> </el-table-column>
+            <el-table-column prop="pic" label="图片" width="80">
                 <template slot-scope="{ row }">
                 <template slot-scope="{ row }">
                     <el-image
                     <el-image
                         style="width: 30px; height: 30px"
                         style="width: 30px; height: 30px"
@@ -58,15 +65,15 @@
                     ></el-image>
                     ></el-image>
                 </template>
                 </template>
             </el-table-column>
             </el-table-column>
-            <el-table-column prop="minter" label="铸造者"> </el-table-column>
             <el-table-column prop="price" label="价格"> </el-table-column>
             <el-table-column prop="price" label="价格"> </el-table-column>
             <el-table-column prop="gasPrice" label="gas费"> </el-table-column>
             <el-table-column prop="gasPrice" label="gas费"> </el-table-column>
             <el-table-column prop="totalPrice" label="总价"> </el-table-column>
             <el-table-column prop="totalPrice" label="总价"> </el-table-column>
             <el-table-column prop="status" label="状态" :formatter="statusFormatter"> </el-table-column>
             <el-table-column prop="status" label="状态" :formatter="statusFormatter"> </el-table-column>
             <el-table-column prop="payMethod" label="支付方式" :formatter="payMethodFormatter"> </el-table-column>
             <el-table-column prop="payMethod" label="支付方式" :formatter="payMethodFormatter"> </el-table-column>
             <el-table-column prop="transactionId" label="交易ID"> </el-table-column>
             <el-table-column prop="transactionId" label="交易ID"> </el-table-column>
-            <el-table-column prop="payTime" label="支付时间"> </el-table-column>
-            <el-table-column prop="txHash" label="链上hash"> </el-table-column>
+            <el-table-column prop="createdAt" label="创建时间" width="140"> </el-table-column>
+            <el-table-column prop="payTime" label="支付时间" width="140"> </el-table-column>
+            <el-table-column prop="txHash" label="链上hash" show-overflow-tooltip> </el-table-column>
             <el-table-column prop="gasUsed" label="消耗gas"> </el-table-column>
             <el-table-column prop="gasUsed" label="消耗gas"> </el-table-column>
             <el-table-column label="操作" align="center" fixed="right" width="150">
             <el-table-column label="操作" align="center" fixed="right" width="150">
                 <template slot-scope="{ row }">
                 <template slot-scope="{ row }">
@@ -120,7 +127,8 @@ export default {
             payMethodOptions: [
             payMethodOptions: [
                 { label: '微信', value: 'WEIXIN' },
                 { label: '微信', value: 'WEIXIN' },
                 { label: '支付宝', value: 'ALIPAY' }
                 { label: '支付宝', value: 'ALIPAY' }
-            ]
+            ],
+            status: null
         };
         };
     },
     },
     computed: {
     computed: {
@@ -144,7 +152,7 @@ export default {
             return '';
             return '';
         },
         },
         beforeGetData() {
         beforeGetData() {
-            return { search: this.search, query: { del: false } };
+            return { search: this.search, query: { del: false, status: this.status } };
         },
         },
         toggleMultipleMode(multipleMode) {
         toggleMultipleMode(multipleMode) {
             this.multipleMode = multipleMode;
             this.multipleMode = multipleMode;