BackpackDialog.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <template>
  2. <custom-dialog
  3. :visible.sync="dialogVisible"
  4. title=""
  5. content-width="720rpx"
  6. closeImg="/static/island/UI/btn_close.png"
  7. closeImgTop="120rpx"
  8. background-color="transparent"
  9. @close="onClose"
  10. >
  11. <view class="backpack-content">
  12. <view class="backpack-name">背包</view>
  13. <view class="backpack-items">
  14. <view
  15. class="backpack-grid"
  16. v-for="index in 80"
  17. :key="index"
  18. @click="onGridClick(index-1)"
  19. >
  20. <view
  21. class="item-grid"
  22. :class="{'selected': selectedIndex === index-1 && items[index-1]}"
  23. >
  24. <template v-if="items[index-1]">
  25. <text class="count-text">{{items[index-1].count}}</text>
  26. <image class="item-icon" :src="items[index-1].icon" mode="aspectFit"></image>
  27. <text class="item-name">{{items[index-1].name}}</text>
  28. </template>
  29. </view>
  30. </view>
  31. </view>
  32. <view class="backpack-bottom">
  33. <view class="bottom-info">
  34. <text>{{selectedItem ? selectedItem.description : '请选择道具查看详情'}}</text>
  35. </view>
  36. <view class="bottom-actions">
  37. <view class="coin-info">
  38. <image class="currency-icon" src="/static/island/UI/wd_icon_xingyuan.png" mode="aspectFit"></image>
  39. <text>{{selectedItem ? selectedItem.price : 0}}</text>
  40. </view>
  41. <view class="sell-btn" :class="{'disabled': !selectedItem}" @click="showSellConfirm">售卖</view>
  42. </view>
  43. </view>
  44. </view>
  45. <!-- 确认出售对话框 -->
  46. <view class="confirm-dialog" v-if="showSellDialog">
  47. <view class="dialog-content">
  48. <view class="dialog-title">确认出售</view>
  49. <view class="dialog-text">是否出售{{selectedItem ? selectedItem.count : 0}}个{{selectedItem ? selectedItem.name : ''}},获得铃钱:{{selectedItem ? selectedItem.count * selectedItem.price : 0}}?</view>
  50. <view class="dialog-buttons">
  51. <view class="btn-cancel" @click="cancelSell">取消</view>
  52. <view class="btn-confirm" @click="confirmSell">确认</view>
  53. </view>
  54. </view>
  55. </view>
  56. </custom-dialog>
  57. </template>
  58. <script>
  59. import CustomDialog from '../CustomDialog/CustomDialog.vue'
  60. export default {
  61. name: 'BackpackDialog',
  62. components: {
  63. CustomDialog
  64. },
  65. props: {
  66. visible: {
  67. type: Boolean,
  68. default: false
  69. }
  70. },
  71. data() {
  72. return {
  73. dialogVisible: false,
  74. selectedIndex: -1,
  75. items: [],
  76. loading: false,
  77. showSellDialog: false // 添加确认出售对话框显示状态
  78. }
  79. },
  80. computed: {
  81. selectedItem() {
  82. return this.selectedIndex >= 0 && this.selectedIndex < this.items.length
  83. ? this.items[this.selectedIndex]
  84. : null
  85. }
  86. },
  87. watch: {
  88. visible(val) {
  89. this.dialogVisible = val
  90. if(val) {
  91. this.fetchBagList()
  92. }
  93. },
  94. dialogVisible(val) {
  95. this.$emit('update:visible', val)
  96. }
  97. },
  98. methods: {
  99. fetchBagList() {
  100. this.loading = true
  101. uni.request({
  102. url: this.$apiHost + '/Game/get_bag_list',
  103. method: 'GET',
  104. data: {
  105. uuid: getApp().globalData.uuid,
  106. },
  107. header: {
  108. 'Content-Type': 'application/x-www-form-urlencoded',
  109. 'sign': getApp().globalData.headerSign,
  110. },
  111. success: (res) => {
  112. if (res.data.code === 0) {
  113. this.items = res.data.data.bagList.map(item => ({
  114. id: item.id,
  115. tid: item.tid,
  116. type: item.type,
  117. count: item.num,
  118. name: item.name,
  119. icon: item.image,
  120. description: `这是一个${item.name},数量:${item.num}`,
  121. price: item.price // 这里可以根据实际需求设置价格
  122. }))
  123. // 默认选中第一个有道具的格子
  124. this.selectedIndex = this.items.length > 0 ? 0 : -1
  125. } else {
  126. uni.showToast({
  127. title: res.data.msg || '获取背包数据失败',
  128. icon: 'none'
  129. })
  130. }
  131. },
  132. fail: (err) => {
  133. console.error('获取背包数据失败:', err)
  134. uni.showToast({
  135. title: '获取背包数据失败',
  136. icon: 'none'
  137. })
  138. },
  139. complete: () => {
  140. this.loading = false
  141. }
  142. })
  143. },
  144. onClose() {
  145. this.dialogVisible = false
  146. },
  147. onGridClick(index) {
  148. if(this.items[index]) {
  149. this.selectedIndex = index
  150. this.$emit('select', this.items[index])
  151. }
  152. },
  153. // 显示确认出售对话框
  154. showSellConfirm() {
  155. if(!this.selectedItem) return
  156. this.showSellDialog = true
  157. },
  158. // 取消出售
  159. cancelSell() {
  160. this.showSellDialog = false
  161. },
  162. // 确认出售
  163. confirmSell() {
  164. if(!this.selectedItem) return
  165. const item = this.selectedItem
  166. uni.request({
  167. url: this.$apiHost + '/Game/sell_bag_item',
  168. method: 'POST',
  169. data: {
  170. uuid: getApp().globalData.uuid,
  171. bag_id: item.id
  172. },
  173. header: {
  174. 'Content-Type': 'application/x-www-form-urlencoded',
  175. 'sign': getApp().globalData.headerSign,
  176. },
  177. success: (res) => {
  178. if (res.data.code === 0) {
  179. uni.showToast({
  180. title: '出售成功',
  181. icon: 'success'
  182. })
  183. // 刷新背包列表
  184. this.fetchBagList()
  185. // 通知父组件更新铃钱
  186. this.$emit('money-change', res.data.data.money)
  187. } else {
  188. uni.showToast({
  189. title: res.data.msg || '出售失败',
  190. icon: 'none'
  191. })
  192. }
  193. },
  194. fail: (err) => {
  195. console.error('出售失败:', err)
  196. uni.showToast({
  197. title: '出售失败',
  198. icon: 'none'
  199. })
  200. }
  201. })
  202. this.showSellDialog = false
  203. }
  204. }
  205. }
  206. </script>
  207. <style lang="scss" scoped>
  208. @import './BackpackDialog.scss';
  209. // 添加确认对话框样式
  210. .confirm-dialog {
  211. position: fixed;
  212. top: 0;
  213. left: 0;
  214. width: 100%;
  215. height: 100%;
  216. background-color: rgba(0, 0, 0, 0.5);
  217. display: flex;
  218. justify-content: center;
  219. align-items: center;
  220. z-index: 999;
  221. .dialog-content {
  222. width: 500rpx;
  223. background: #FDDEC1;
  224. border-radius: 20rpx;
  225. overflow: hidden;
  226. box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.1);
  227. border: 2rpx solid #d06262;
  228. .dialog-title {
  229. text-align: center;
  230. color: #683830;
  231. font-size: 34rpx;
  232. font-weight: bold;
  233. padding: 20rpx 0;
  234. border-bottom: 0rpx solid #d06262;
  235. position: relative;
  236. }
  237. .dialog-text {
  238. padding: 40rpx 30rpx;
  239. text-align: center;
  240. font-size: 30rpx;
  241. color: #987453;
  242. border-radius: 0 0 12rpx 12rpx;
  243. position: relative;
  244. }
  245. .dialog-buttons {
  246. display: flex;
  247. justify-content: space-around;
  248. padding: 30rpx;
  249. .btn-cancel,
  250. .btn-confirm {
  251. width: 180rpx;
  252. height: 80rpx;
  253. border-radius: 40rpx;
  254. display: flex;
  255. justify-content: center;
  256. align-items: center;
  257. font-size: 32rpx;
  258. font-weight: bold;
  259. width: 184rpx;
  260. height: 80rpx;
  261. background: url('/static/island/huatian/zx_btn_queren.png');
  262. background-size: 184rpx 80rpx;
  263. }
  264. .btn-cancel {
  265. color: white;
  266. position: relative;
  267. width: 184rpx;
  268. height: 80rpx;
  269. background: url('/static/island/huatian/zx_btn_quxiao.png');
  270. background-size: 184rpx 80rpx;
  271. }
  272. .btn-confirm {
  273. color: white;
  274. position: relative;
  275. }
  276. }
  277. }
  278. }
  279. </style>