ShopDialog.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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="50rpx"
  8. background-color="transparent"
  9. @close="onClose"
  10. >
  11. <view class="shop-content">
  12. <!-- <view class="shop-tabs">
  13. <view
  14. v-for="(tab, index) in tabs"
  15. :key="index"
  16. class="tab-item"
  17. :class="{'active': currentTab === index}"
  18. @click="currentTab = index"
  19. >
  20. {{tab}}
  21. </view>
  22. </view> -->
  23. <view class="shop-header"></view>
  24. <view class="shop-name">{{shopName}}</view>
  25. <view class="shop-items">
  26. <view class="shop-item" v-for="(item, index) in shopItems" :key="index" @click="onItemClick(item)">
  27. <view class="item-card">
  28. <view class="new-tag" v-if="item.isNew">新品</view>
  29. <view class="item-left">
  30. <view class="item-grid">
  31. <image class="item-icon" :src="item.image || defaultImage" mode="aspectFit"></image>
  32. <text class="owned-text">已有: {{item.num || 0}}</text>
  33. </view>
  34. </view>
  35. <view class="item-center">
  36. <text class="item-name">{{item.name}}</text>
  37. <view class="item-details">
  38. <text class="detail-text">{{getItemDetail(item)}}</text>
  39. </view>
  40. </view>
  41. <view class="item-right">
  42. <view class="buy-btn" @click.stop="buyItem(item)">
  43. <view class="item-price">
  44. <image class="currency-icon" src="/static/island/UI/wd_icon_xingyuan.png" mode="aspectFit"></image>
  45. <text>{{item.price}}</text>
  46. </view>
  47. </view>
  48. </view>
  49. </view>
  50. </view>
  51. </view>
  52. </view>
  53. </custom-dialog>
  54. </template>
  55. <script>
  56. import CustomDialog from '../CustomDialog/CustomDialog.vue'
  57. export default {
  58. name: 'ShopDialog',
  59. components: {
  60. CustomDialog
  61. },
  62. props: {
  63. visible: {
  64. type: Boolean,
  65. default: false
  66. },
  67. shopName: {
  68. type: String,
  69. default: '商店'
  70. }
  71. },
  72. data() {
  73. return {
  74. dialogVisible: false,
  75. currentTab: 0,
  76. tabs: ['种子', '道具', '钻石'],
  77. shopItems: [],
  78. defaultImage: '/static/island/items/default.png',
  79. shopType: 'main', // 默认商店类型
  80. userMoney: 0, // 用户铃钱
  81. loading: false
  82. }
  83. },
  84. computed: {
  85. currentItems() {
  86. return this.items[this.currentTab]
  87. }
  88. },
  89. watch: {
  90. visible(val) {
  91. this.dialogVisible = val
  92. if (val) {
  93. // this.fetchShopData()
  94. }
  95. },
  96. dialogVisible(val) {
  97. this.$emit('update:visible', val)
  98. },
  99. shopName: {
  100. immediate: true,
  101. handler(val) {
  102. console.log("shopName",val)
  103. if (val === '材料商店') {
  104. this.shopType = 'main'
  105. } else if (val === '花店') {
  106. this.shopType = 'huatian'
  107. } else {
  108. this.shopType = 'main'
  109. }
  110. // 如果对话框可见,则重新获取数据
  111. if (this.dialogVisible) {
  112. }
  113. this.fetchShopData()
  114. }
  115. }
  116. },
  117. methods: {
  118. onClose() {
  119. this.dialogVisible = false
  120. },
  121. onItemClick(item) {
  122. this.$emit('buy', item)
  123. },
  124. // 获取商店数据
  125. async fetchShopData() {
  126. if (this.loading) return
  127. this.loading = true
  128. console.log("shoptype",this.shopType)
  129. try {
  130. uni.request({
  131. url: this.$apiHost + '/Game/get_shop_list',
  132. method: 'GET',
  133. data: {
  134. uuid: getApp().globalData.uuid,
  135. type: this.shopType
  136. },
  137. header: {
  138. 'Content-Type': 'application/x-www-form-urlencoded',
  139. 'sign': getApp().globalData.headerSign,
  140. },
  141. success: (res) => {
  142. console.log("res",res.data)
  143. if (res.data && res.data.code === 0) {
  144. this.shopItems = res.data.list || []
  145. // 获取用户铃钱
  146. this.getUserMoney()
  147. } else {
  148. uni.showToast({
  149. title: res.data?.msg || '获取商店数据失败',
  150. icon: 'none'
  151. })
  152. }
  153. },
  154. fail: (err) => {
  155. console.error('获取商店数据异常', err)
  156. uni.showToast({
  157. title: '网络异常,请重试',
  158. icon: 'none'
  159. })
  160. },
  161. complete: () => {
  162. this.loading = false
  163. }
  164. })
  165. } catch (error) {
  166. console.error('获取商店数据异常', error)
  167. uni.showToast({
  168. title: '网络异常,请重试',
  169. icon: 'none'
  170. })
  171. this.loading = false
  172. }
  173. },
  174. // 获取用户铃钱
  175. getUserMoney() {
  176. uni.request({
  177. url: this.$apiHost + '/User/getinfo',
  178. method: 'GET',
  179. data: {
  180. uuid: getApp().globalData.uuid
  181. },
  182. header: {
  183. 'Content-Type': 'application/x-www-form-urlencoded',
  184. 'sign': getApp().globalData.headerSign,
  185. },
  186. success: (res) => {
  187. if (res.data && res.data.code === 0) {
  188. this.userMoney = res.data.num_gmg || 0
  189. }
  190. }
  191. })
  192. },
  193. // 购买物品
  194. buyItem(item) {
  195. if (this.userMoney < item.price) {
  196. uni.showToast({
  197. title: '铃钱不足',
  198. icon: 'none'
  199. })
  200. return
  201. }
  202. uni.request({
  203. url: this.$apiHost + '/Game/buy_shop_item',
  204. method: 'POST',
  205. data: {
  206. uuid: getApp().globalData.uuid,
  207. shop_id: item.id
  208. },
  209. header: {
  210. 'Content-Type': 'application/x-www-form-urlencoded',
  211. 'sign': getApp().globalData.headerSign,
  212. },
  213. success: (res) => {
  214. if (res.data && res.data.code === 0) {
  215. uni.showToast({
  216. title: '购买成功',
  217. icon: 'success'
  218. })
  219. // 更新用户铃钱
  220. this.userMoney = res.data.data.money
  221. // 更新物品数量
  222. const index = this.shopItems.findIndex(i => i.id === item.id)
  223. if (index !== -1) {
  224. this.shopItems[index].num = (this.shopItems[index].num || 0) + 1
  225. }
  226. // 通知父组件购买成功
  227. this.$emit('buy-success', item)
  228. } else {
  229. uni.showToast({
  230. title: res.data?.msg || '购买失败',
  231. icon: 'none'
  232. })
  233. }
  234. },
  235. fail: (err) => {
  236. console.error('购买物品异常', err)
  237. uni.showToast({
  238. title: '网络异常,请重试',
  239. icon: 'none'
  240. })
  241. }
  242. })
  243. },
  244. // 获取物品详情
  245. getItemDetail(item) {
  246. if (this.shopType === 'huatian') {
  247. return `收获期: ${item.limit_time}时\n产量: ${item.num_out}`
  248. } else {
  249. return item.content || '暂无描述'
  250. }
  251. }
  252. }
  253. }
  254. </script>
  255. <style lang="scss" scoped>
  256. @import './ShopDialog.scss';
  257. </style>