1
0

2 Ревизии ad40aec130 ... 6bb2442c4e

Автор SHA1 Съобщение Дата
  lalalashen 6bb2442c4e Merge branch 'master' of http://150.158.33.144:3000/lalalashen/MoeNovaClient преди 2 месеца
  lalalashen b86423fcf9 商店和背包上传 преди 2 месеца

+ 5 - 2
components/CustomDialog/CustomDialog.vue

@@ -1,7 +1,7 @@
 <template>
   <view class="custom-dialog" v-if="visible">
     <view class="dialog-mask" @click="closeDialog"></view>
-    <view class="dialog-content" :class="{'dialog-show': visible}" :animation="animationData" :style="{ width: contentWidth }">
+    <view class="dialog-content" :class="{'dialog-show': visible}" :animation="animationData" :style="{ width: contentWidth, background: backgroundColor }">
       <view class="dialog-header" v-if="title && title.length > 0">
         <text class="dialog-title">{{title}}</text>
       </view>
@@ -30,6 +30,10 @@ export default {
       type: String,
       default: '600rpx'
     },
+    backgroundColor: {
+      type: String,
+      default: '#fff'
+    },
     closeImg: {
       type: String,
       default: ''
@@ -109,7 +113,6 @@ export default {
   
   .dialog-content {
     position: relative;
-    background: #fff;
     border-radius: 16rpx;
     overflow: hidden;
     opacity: 0;

+ 175 - 0
components/dialogs/BackpackDialog.scss

@@ -0,0 +1,175 @@
+.backpack-content {
+  margin-top: 150rpx;
+  margin-left: 10rpx;
+  background: url('/static/island/UI/kuang.png') no-repeat center center;
+  background-size: cover;
+  width: 702rpx;
+  height: 998rpx;
+  display: flex;
+  flex-direction: column;
+
+  .backpack-name {
+    width: 300rpx;
+    height: 60rpx;
+    margin: 0 auto;
+    background: url('/static/island/UI/title_bg.png') no-repeat center center;
+    background-size: 100% 100%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    color: #FFF;
+    font-size: 32rpx;
+    font-weight: bold;
+    margin-top: 40rpx;
+    margin-bottom: 20rpx;
+  }
+
+  .backpack-items {
+    flex: 1;
+    display: grid;
+    grid-template-columns: repeat(4, 150rpx);
+    grid-template-rows: repeat(20, 150rpx);
+    gap: 10rpx;
+    padding: 10rpx;
+    overflow-y: auto;
+    margin-bottom: 10rpx;
+    justify-content: center;
+
+    &::-webkit-scrollbar {
+      width: 6rpx;
+    }
+    
+    &::-webkit-scrollbar-thumb {
+      background: rgba(166, 124, 82, 0.3);
+      border-radius: 3rpx;
+    }
+    
+    &::-webkit-scrollbar-track {
+      background: transparent;
+    }
+
+    .backpack-grid {
+      .item-grid {
+        position: relative;
+        width: 150rpx;
+        height: 150rpx;
+        background: #FBD6A9;
+        border-radius: 16rpx;
+        padding: 5rpx;
+        box-sizing: border-box;
+        border: 2rpx solid #DEB691;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        cursor: pointer;
+
+        &.selected {
+          border: 4rpx solid #84B654;
+          background: #E8F5E9;
+        }
+
+        .item-icon {
+          width: 130rpx;
+          height: 130rpx;
+          object-fit: contain;
+        }
+
+        .count-text {
+          position: absolute;
+          top: 5rpx;
+          right: 5rpx;
+          font-size: 20rpx;
+          color: #FFFFFF;
+          text-shadow: 1rpx 1rpx 0 #A95F3C,
+                      -1rpx 1rpx 0 #A95F3C,
+                      1rpx -1rpx 0 #A95F3C,
+                      -1rpx -1rpx 0 #A95F3C;
+          padding: 2rpx 8rpx;
+          min-width: 32rpx;
+          text-align: center;
+        }
+
+        .item-name {
+          font-size: 20rpx;
+          color: #A95F3C;
+          white-space: normal;
+          line-height: 1.2;
+          width: 95%;
+          background: rgba(255, 255, 255, 0.8);
+          position: absolute;
+          bottom: 5rpx;
+          left: 50%;
+          transform: translateX(-50%);
+          border-radius: 0 0 10rpx 10rpx;
+          text-align: center;
+          padding: 2rpx 0;
+        }
+      }
+    }
+  }
+
+  .backpack-bottom {
+    background: #FFF1E4;
+    border-radius: 0 0 30rpx 30rpx;
+    margin: 0 20rpx 20rpx;
+    padding: 15rpx;
+
+    .bottom-info {
+      text-align: center;
+      color: #987453;
+      font-size: 24rpx;
+      line-height: 1.4;
+      margin-bottom: 10rpx;
+      min-height: 60rpx;
+    }
+
+    .bottom-actions {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0 20rpx;
+
+      .coin-info {
+        display: flex;
+        align-items: center;
+        gap: 10rpx;
+
+        .currency-icon {
+          width: 32rpx;
+          height: 32rpx;
+        }
+
+        text {
+          color: #987453;
+          font-size: 28rpx;
+          font-weight: bold;
+          text-align: left;
+        }
+      }
+
+      .sell-btn {
+        min-width: 150rpx;
+        height: 55rpx;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        font-size: 24rpx;
+        color: #ffffff;
+        background-image: url('/static/island/UI/btn_green.png');
+        background-size: 100% 100%;
+        background-repeat: no-repeat;
+        cursor: pointer;
+
+        &.disabled {
+          opacity: 0.5;
+          cursor: not-allowed;
+        }
+
+        &:active:not(.disabled) {
+          transform: scale(0.95);
+          opacity: 0.9;
+        }
+      }
+    }
+  }
+} 

+ 159 - 0
components/dialogs/BackpackDialog.vue

@@ -0,0 +1,159 @@
+<template>
+  <custom-dialog 
+    :visible.sync="dialogVisible" 
+    title="" 
+    content-width="720rpx" 
+    closeImg="/static/island/UI/btn_close.png" 
+    closeImgTop="120rpx" 
+    background-color="transparent"
+    @close="onClose"
+  >
+    <view class="backpack-content">
+      <view class="backpack-name">背包</view>
+      <view class="backpack-items">
+        <view 
+          class="backpack-grid" 
+          v-for="index in 80" 
+          :key="index"
+          @click="onGridClick(index-1)"
+        >
+          <view 
+            class="item-grid"
+            :class="{'selected': selectedIndex === index-1 && items[index-1]}"
+          >
+            <template v-if="items[index-1]">
+              <text class="count-text">{{items[index-1].count}}</text>
+              <image class="item-icon" :src="items[index-1].icon" mode="aspectFit"></image>
+              <text class="item-name">{{items[index-1].name}}</text>
+            </template>
+          </view>
+        </view>
+      </view>
+      <view class="backpack-bottom">
+        <view class="bottom-info">
+          <text>{{selectedItem ? selectedItem.description : '请选择道具查看详情'}}</text>
+        </view>
+        <view class="bottom-actions">
+          <view class="coin-info">
+            <image class="currency-icon" src="/static/island/UI/wd_icon_xingyuan.png" mode="aspectFit"></image>
+            <text>{{selectedItem ? selectedItem.price : 0}}</text>
+          </view>
+          <view class="sell-btn" :class="{'disabled': !selectedItem}" @click="onSellClick">售卖</view>
+        </view>
+      </view>
+    </view>
+  </custom-dialog>
+</template>
+
+<script>
+import CustomDialog from '../CustomDialog/CustomDialog.vue'
+
+export default {
+  name: 'BackpackDialog',
+  components: {
+    CustomDialog
+  },
+  props: {
+    visible: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      dialogVisible: false,
+      selectedIndex: -1,
+      items: [
+        { 
+          icon: '/static/island/items/item_wood1.png', 
+          count: 999,
+          name: '木材',
+          description: '这是一个木材,可以用来制作各种物品',
+          price: 100
+        },
+        { 
+          icon: '/static/island/items/item_wood2.png', 
+          count: 999,
+          name: '高级木材',
+          description: '这是一个高级木材,可以用来制作高级物品',
+          price: 200
+        },
+        { 
+          icon: '/static/island/items/item_mine1.png', 
+          count: 999,
+          name: '矿石',
+          description: '这是一个矿石,可以用来制作金属物品',
+          price: 150
+        },
+        { 
+          icon: '/static/island/items/item_mine2.png', 
+          count: 999,
+          name: '高级矿石',
+          description: '这是一个高级矿石,可以用来制作高级金属物品',
+          price: 300
+        },
+        { 
+          icon: '/static/island/items/item_axe1.png', 
+          count: 999,
+          name: '斧头',
+          description: '这是一个斧头,可以用来砍伐树木',
+          price: 500
+        }
+      ]
+    }
+  },
+  computed: {
+    selectedItem() {
+      return this.selectedIndex >= 0 && this.selectedIndex < this.items.length 
+        ? this.items[this.selectedIndex] 
+        : null
+    }
+  },
+  watch: {
+    visible(val) {
+      this.dialogVisible = val
+      if(val) {
+        // 默认选中第一个有道具的格子
+        this.selectedIndex = this.items.length > 0 ? 0 : -1
+      }
+    },
+    dialogVisible(val) {
+      this.$emit('update:visible', val)
+    }
+  },
+  methods: {
+    onClose() {
+      this.dialogVisible = false
+    },
+    onGridClick(index) {
+      if(this.items[index]) {
+        this.selectedIndex = index
+        this.$emit('select', this.items[index])
+      }
+    },
+    onSellClick() {
+      if(!this.selectedItem) return
+      
+      const item = this.selectedItem
+      const totalPrice = item.count * item.price
+      
+      uni.showModal({
+        title: '确认出售',
+        content: `出售${item.count}个${item.name},会获得铃钱:${totalPrice},\n确定出售吗?`,
+        confirmText: '确定',
+        cancelText: '取消',
+        success: (res) => {
+          if(res.confirm) {
+            // TODO: 处理出售逻辑
+            this.$emit('sell', item)
+          }
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import './BackpackDialog.scss';
+</style> 

+ 99 - 39
components/dialogs/ShopDialog.scss

@@ -1,13 +1,38 @@
 .shop-content {
-  margin-top: 25rpx;
+  margin-top: 150rpx;
   margin-left: 10rpx;
-  background: url('/static/island/UI/task/rw_bg.png') no-repeat center center;
+  background: url('/static/island/UI/kuang.png') no-repeat center center;
   background-size: cover;
   width: 702rpx;
-  height: 984rpx;
+  height: 998rpx;
   display: flex;
   flex-direction: column;
 
+  .shop-header {
+    margin-top: -60rpx;
+    width: 802rpx;
+    height: 150rpx;
+    margin-left: -50rpx;
+    margin-right: -50rpx;
+    background: url('/static/island/UI/shop/shop_header.png') no-repeat center center;
+    background-size: contain;
+  }
+
+  .shop-name {
+    width: 300rpx;
+    height: 60rpx;
+    margin: 0 auto;
+    background: url('/static/island/UI/title_bg.png') no-repeat center center;
+    background-size: 100% 100%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    color: #FFF;
+    font-size: 32rpx;
+    font-weight: bold;
+    margin-bottom: 20rpx;
+  }
+
   .shop-tabs {
     flex-shrink: 0;
     display: flex;
@@ -72,6 +97,10 @@
         padding: 20rpx;
         display: flex;
         position: relative;
+        width: 90%;
+        margin: 0 auto;
+        align-items: center;
+        justify-content: space-between;
 
         .new-tag {
           position: absolute;
@@ -85,53 +114,98 @@
         }
 
         .item-left {
+          flex-shrink: 0;
           margin-right: 20rpx;
           display: flex;
           flex-direction: column;
           align-items: center;
 
-          .item-icon {
+          .item-grid {
+            position: relative;
+            display: flex;
             width: 120rpx;
             height: 120rpx;
-            background: linear-gradient(to bottom right, #B8E986, #7EC242);
-            border-radius: 16rpx;
-            padding: 10rpx;
-          }
+            .item-icon {
+              width: 120rpx;
+              height: 120rpx;
+              background: #FBD6A9;
+              border-radius: 16rpx;
+              padding: 5rpx;
+              box-sizing: border-box;
+              border: 2rpx solid #DEB691;
+              position: relative;
+              display: flex;
+              flex-direction: column;
+              align-items: center;
+              justify-content: center;
+            }
 
-          .owned-text {
-            margin-top: 10rpx;
-            color: #987453;
-            font-size: 24rpx;
+            .owned-text {
+              font-size: 20rpx;
+              color:#A95F3C;
+              white-space: normal;
+              line-height: 1.2;
+              width: 95%;
+              margin: 12rpx 2rpx 2rpx 2rpx;
+              background: rgba(255, 255, 255, 0.8);
+              position: absolute;
+              bottom: 0;
+              left: 0;
+              right: 0;
+              border-radius: 0 0 16rpx 16rpx;
+              text-align: center;
+            }
           }
         }
 
-        .item-info {
+        .item-center {
           flex: 1;
           display: flex;
           flex-direction: column;
+          align-items: flex-start;
+          margin: 0 20rpx 0 0;
 
           .item-name {
             color: #987453;
-            font-size: 28rpx;
+            font-size: 24rpx;
             font-weight: bold;
-            margin-bottom: 10rpx;
+            margin-bottom: 6rpx;
+            text-align: left;
           }
 
           .item-details {
-            margin-bottom: 20rpx;
+            display: flex;
+            flex-direction: column;
+            align-items: flex-start;
+            gap: 0rpx;
 
             .detail-text {
               color: #987453;
-              font-size: 24rpx;
-              margin-right: 20rpx;
+              font-size: 20rpx;
+              text-align: left;
+              white-space: pre-wrap;
+              line-height: 1.4;
             }
           }
+        }
 
-          .item-bottom {
-            margin-top: auto;
+        .item-right {
+          flex-shrink: 0;
+          
+          .buy-btn {
+            min-width: 150rpx;
+            height: 55rpx;
             display: flex;
-            justify-content: space-between;
+            flex-direction: column;
             align-items: center;
+            justify-content: center;
+            font-size: 24rpx;
+            color: #ffffff;
+            background-image: url('/static/island/UI/btn_green.png');
+            background-size: 100% 100%;
+            background-repeat: no-repeat;
+            border: none;
+            padding: 0;
 
             .item-price {
               display: flex;
@@ -144,29 +218,15 @@
               }
 
               text {
-                color: #987453;
+                color: #fff;
                 font-size: 28rpx;
                 font-weight: bold;
               }
             }
 
-            .buy-btn {
-              min-width: 120rpx;
-              height: 62rpx;
-              line-height: 62rpx;
-              text-align: center;
-              font-size: 24rpx;
-              color: #ffffff;
-              background-image: url('/static/island/UI/btn_yellow.png');
-              background-size: 100% 100%;
-              background-repeat: no-repeat;
-              border: none;
-              padding: 0 20rpx;
-
-              &:active {
-                transform: scale(0.95);
-                opacity: 0.9;
-              }
+            &:active {
+              transform: scale(0.95);
+              opacity: 0.9;
             }
           }
         }

+ 45 - 27
components/dialogs/ShopDialog.vue

@@ -4,11 +4,12 @@
     title="" 
     content-width="720rpx" 
     closeImg="/static/island/UI/btn_close.png" 
-    closeImgTop="0rpx" 
+    closeImgTop="50rpx" 
+    background-color="transparent"
     @close="onClose"
   >
     <view class="shop-content">
-      <view class="shop-tabs">
+      <!-- <view class="shop-tabs">
         <view 
           v-for="(tab, index) in tabs" 
           :key="index"
@@ -18,28 +19,31 @@
         >
           {{tab}}
         </view>
-      </view>
+      </view> -->
+      <view class="shop-header"></view>
+      <view class="shop-name">{{shopName}}</view>
       <view class="shop-items">
         <view class="shop-item" v-for="(item, index) in currentItems" :key="index" @click="onItemClick(item)">
           <view class="item-card">
             <view class="new-tag" v-if="item.isNew">新品</view>
             <view class="item-left">
-              <image class="item-icon" :src="item.icon" mode="aspectFit"></image>
-              <text class="owned-text">已持有: {{item.owned}}</text>
+              <view class="item-grid">
+                <image class="item-icon" :src="item.icon" mode="aspectFit"></image>
+                <text class="owned-text">已有: {{item.owned}}</text>
+              </view>
             </view>
-            <view class="item-info">
+            <view class="item-center">
               <text class="item-name">{{item.name}}</text>
               <view class="item-details">
-                <text class="detail-text">收获期: {{item.harvestTime}}</text>
-                <text class="detail-text">成长期: {{item.growthTime}}</text>
-                <text class="detail-text">产量: {{item.yield}}</text>
+                <text class="detail-text">{{item.detail}}</text>
               </view>
-              <view class="item-bottom">
+            </view>
+            <view class="item-right">
+              <view class="buy-btn">
                 <view class="item-price">
-                  <image class="currency-icon" src="/static/currency/coin.png" mode="aspectFit"></image>
+                  <image class="currency-icon" src="/static/island/UI/wd_icon_xingyuan.png" mode="aspectFit"></image>
                   <text>{{item.price}}</text>
                 </view>
-                <button class="buy-btn">购买</button>
               </view>
             </view>
           </view>
@@ -61,6 +65,10 @@ export default {
     visible: {
       type: Boolean,
       default: false
+    },
+    shopName: {
+      type: String,
+      default: '商店'
     }
   },
   data() {
@@ -71,34 +79,44 @@ export default {
       items: {
         0: [
           { 
-            icon: '/static/items/seed1.png', 
+            icon: '/static/island/items/item_wood1.png', 
             name: '草莓种子', 
-            harvestTime: '160时', 
-            growthTime: '60时',
-            yield: '10',
+            detail: '收获期: 160时\n成长期: 60时\n产量: 10',
             price: 100,
             owned: 3,
-            isNew: true
+            isNew: false
           },
           { 
-            icon: '/static/items/seed1.png', 
+            icon: '/static/island/items/item_wood2.png', 
             name: '草莓种子', 
-            harvestTime: '160时', 
-            growthTime: '60时',
-            yield: '10',
+            detail: '收获期: 160时\n成长期: 60时\n产量: 10',
             price: 100,
             owned: 3,
-            isNew: true
+            isNew: false
           },
           { 
-            icon: '/static/items/seed1.png', 
+            icon: '/static/island/items/item_mine1.png', 
             name: '草莓种子', 
-            harvestTime: '160时', 
-            growthTime: '60时',
-            yield: '10',
+            detail: '收获期: 160时\n成长期: 60时\n产量: 10',
+            price: 100,
+            owned: 3,
+            isNew: false
+          },
+          { 
+            icon: '/static/island/items/item_mine2.png', 
+            name: '铁矿石', 
+            detail: '收获期: 160时\n成长期: 60时\n产量: 10',
+            price: 100,
+            owned: 3,
+            isNew: false
+          },
+          { 
+            icon: '/static/island/items/item_axe1.png', 
+            name: '斧头', 
+            detail: '收获期: 160时\n成长期: 60时\n产量: 10',
             price: 100,
             owned: 3,
-            isNew: true
+            isNew: false
           }
         ],
         1: [],

+ 3 - 3
pages/isLand/homeLand.vue

@@ -53,7 +53,7 @@
     </view>
 
     <!-- 对话框组件 -->
-    <inventory-dialog :visible.sync="inventoryVisible" @close="onInventoryClose"></inventory-dialog>
+    <backpack-dialog :visible.sync="inventoryVisible" @close="onInventoryClose"></backpack-dialog>
     <character-dialog :visible.sync="characterVisible" @close="onCharacterClose"></character-dialog>
     <shop-dialog :visible.sync="shopVisible" @close="onShopClose" @buy="onShopBuy"></shop-dialog>
     <task-dialog class="task-dialog" :visible.sync="taskVisible" @close="onTaskClose"></task-dialog>
@@ -72,7 +72,7 @@
 
 
 <script>
-import InventoryDialog from '@/components/dialogs/InventoryDialog.vue'
+import BackpackDialog from '@/components/dialogs/BackpackDialog.vue'
 import CharacterDialog from '@/components/dialogs/CharacterDialog.vue'
 import ShopDialog from '@/components/dialogs/ShopDialog.vue'
 import TaskDialog from './TaskDialog.vue'
@@ -81,7 +81,7 @@ import CraftingDialog from '@/components/dialogs/CraftingDialog.vue'
 
 export default {
 	components: {
-		InventoryDialog,
+		BackpackDialog,
 		CharacterDialog,
 		ShopDialog,
 		TaskDialog,

BIN
static/island/UI/kuang.png


BIN
static/island/UI/shop/shop_header.png


BIN
static/island/UI/title_bg.png