job.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. <template>
  2. <view class="page">
  3. <!-- 顶部黄色背景 -->
  4. <view class="top-bg"></view>
  5. <!-- 内容区域 -->
  6. <view class="content-area">
  7. <!-- 彩豆余额展示区 -->
  8. <view class="bean-balance">
  9. <view class="balance-header">
  10. <view class="title-area">
  11. <view class="yellow-dot"></view>
  12. <text class="my-bean-title">我的彩豆</text>
  13. </view>
  14. <view class="exchange-btn" @click="showExchangePopup">兑换</view>
  15. </view>
  16. <view class="bean-number">{{num_gmd}}</view>
  17. </view>
  18. <!-- 星愿打卡区域 -->
  19. <view class="sign-cards">
  20. <view class="card purple-card">
  21. <view class="card-title">初次见面礼</view>
  22. <view class="card-desc">完善个人资料可得</view>
  23. <view class="card-reward">奖励+100彩豆</view>
  24. <view class="card-progress">{{newer_bfb}}</view>
  25. </view>
  26. <view class="card yellow-card">
  27. <view class="card-title">每日签到</view>
  28. <view class="card-desc">连续签到奖励更多</view>
  29. <view class="sign-btn" @click="showSignPopup">立即签到</view>
  30. </view>
  31. </view>
  32. <!-- 每日任务列表 -->
  33. <view class="task-list">
  34. <view class="task-header">
  35. <text class="task-title">每日任务</text>
  36. <text class="task-subtitle">获取免费彩豆</text>
  37. </view>
  38. <!-- 任务项列表 -->
  39. <view class="task-item" v-for="(item, index) in taskList" :key="index">
  40. <view class="task-info">
  41. <view class="task-name">{{item.name}}</view>
  42. <view class="task-desc">{{item.content}}</view>
  43. </view>
  44. <view class="task-reward">+{{item.num}}彩豆</view>
  45. <view class="task-btn" :class="{'task-completed': item.status == 9}" @click="claimReward(index)">
  46. {{item.status == 9 ? '已领取' : '领取'}}
  47. </view>
  48. </view>
  49. </view>
  50. </view>
  51. <!-- 彩豆兑换弹窗 -->
  52. <view class="exchange-popup" v-if="showExchange">
  53. <view class="popup-mask" @click="hideExchangePopup"></view>
  54. <view class="popup-content">
  55. <!-- 弹窗顶部信息栏 -->
  56. <view class="popup-header">
  57. <text class="available-balance">可用M币: 14500</text>
  58. <text class="exchange-title">兑换彩豆</text>
  59. </view>
  60. <!-- 兑换区域主体 -->
  61. <view class="exchange-area">
  62. <view class="exchange-title-area">
  63. <text class="exchange-main-title">M币兑换彩豆数</text>
  64. <text class="exchange-subtitle">兑换彩豆数必须是10的倍数</text>
  65. </view>
  66. <view class="input-area">
  67. <view class="bean-icon"></view>
  68. <input type="number" class="exchange-input" placeholder="请输入兑换彩豆数量" v-model="exchangeAmount" />
  69. </view>
  70. <!-- 操作按钮 -->
  71. <view class="action-area">
  72. <view class="exchange-btn-large" @click="confirmExchange">立即兑换彩豆</view>
  73. <text class="tips-text">彩豆可用于创作(生成图片、音乐等AI创作功能)</text>
  74. </view>
  75. </view>
  76. </view>
  77. </view>
  78. <!-- 签到弹窗 -->
  79. <view class="sign-popup" v-if="showSign">
  80. <view class="popup-mask" @click="hideSignPopup"></view>
  81. <view class="sign-popup-content">
  82. <!-- 弹窗顶部 -->
  83. <view class="sign-popup-header">
  84. <text class="sign-popup-title">每日签到领好礼</text>
  85. <view class="sign-notify-switch">
  86. <text class="sign-notify-text">签到消息提醒</text>
  87. <switch class="sign-switch" color="#9C27B0" :checked="signNotify" @change="toggleSignNotify" />
  88. </view>
  89. <view class="sign-days-tag">已签到{{signInfo.signDay}}天</view>
  90. </view>
  91. <!-- VIP特权区域 -->
  92. <view class="vip-area">
  93. <view class="vip-left">
  94. <text class="vip-text">VIP十通会员,签到享专属好礼</text>
  95. </view>
  96. <view class="vip-right">
  97. <text class="vip-offer">限时优惠 ></text>
  98. </view>
  99. </view>
  100. <!-- 签到奖励网格布局 -->
  101. <view class="sign-grid">
  102. <view class="sign-grid-item" v-for="(item, index) in signRewards" :key="index"
  103. :class="{'sign-received': index < signInfo.signDay || (index === signInfo.signDay - 1 && signInfo.isSigned)}">
  104. <view class="sign-day-num">{{item.dayNum}}</view>
  105. <view class="sign-item-img"></view>
  106. <view class="sign-item-name">{{item.reward}}</view>
  107. <view class="sign-vip-tag" v-if="item.isVip">VIP</view>
  108. <view class="sign-received-mask" v-if="index < signInfo.signDay || (index === signInfo.signDay - 1 && signInfo.isSigned)">
  109. <text class="received-text">已领取</text>
  110. </view>
  111. </view>
  112. </view>
  113. <!-- 底部签到按钮 -->
  114. <view class="sign-btn-large"
  115. :class="{'sign-btn-disabled': signInfo.isSigned}"
  116. @click="confirmSign">
  117. {{signInfo.isSigned ? '今日已签到' : '签到领取奖励'}}
  118. </view>
  119. </view>
  120. </view>
  121. <!-- 提示框 -->
  122. <DialogBox ref="DialogBox"></DialogBox>
  123. </view>
  124. </template>
  125. <script>
  126. export default {
  127. components: {},
  128. data() {
  129. return {
  130. title: '任务中心',
  131. myinfo: {},
  132. realname: '',
  133. num_gmd: 0,
  134. newer_bfb: '',
  135. beanBalance: 2560,
  136. showExchange: false,
  137. exchangeAmount: '',
  138. mCoinBalance: 14500,
  139. showSign: false,
  140. signNotify: true,
  141. signRewards: [{
  142. dayNum: '01',
  143. reward: '10彩豆',
  144. isVip: false
  145. },
  146. {
  147. dayNum: '02',
  148. reward: '15彩豆',
  149. isVip: false
  150. },
  151. {
  152. dayNum: '03',
  153. reward: '20彩豆',
  154. isVip: false
  155. },
  156. {
  157. dayNum: '04',
  158. reward: '25彩豆',
  159. isVip: false
  160. },
  161. {
  162. dayNum: '05',
  163. reward: '30彩豆',
  164. isVip: false
  165. },
  166. {
  167. dayNum: '06',
  168. reward: '35彩豆',
  169. isVip: true
  170. },
  171. {
  172. dayNum: '07',
  173. reward: '50彩豆',
  174. isVip: true
  175. }
  176. ],
  177. signInfo: {
  178. signDay: 1,
  179. isSigned: false,
  180. reward: 0
  181. },
  182. taskList: []
  183. }
  184. },
  185. onLoad() {
  186. this.loadData();
  187. this.getSignInfo();
  188. },
  189. onShow() {},
  190. methods: {
  191. onBack() {},
  192. loadData() {
  193. uni.request({
  194. url: this.$apiHost + '/Job/getlist',
  195. data: {
  196. uuid: getApp().globalData.uuid
  197. },
  198. header: {
  199. "content-type": "application/json",
  200. 'sign': getApp().globalData.headerSign
  201. },
  202. success: (res) => {
  203. console.log("----:", res.data);
  204. this.num_gmd = res.data.num_gmd;
  205. this.newer_bfb = res.data.newer_bfb;
  206. this.taskList = res.data.list;
  207. },
  208. complete: (com) => {
  209. // uni.hideLoading();
  210. },
  211. fail: (e) => {
  212. console.log("----e:", e);
  213. }
  214. });
  215. },
  216. // 获取签到信息
  217. getSignInfo() {
  218. uni.request({
  219. url: this.$apiHost + '/User/sign7Day',
  220. data: {
  221. uuid: getApp().globalData.uuid,
  222. action: 'get'
  223. },
  224. header: {
  225. "content-type": "application/json",
  226. 'sign': getApp().globalData.headerSign
  227. },
  228. success: (res) => {
  229. if(res.data.success === 'yes') {
  230. this.signInfo = {
  231. signDay: res.data.data.sign_day,
  232. isSigned: res.data.data.is_signed,
  233. reward: res.data.data.reward || 0
  234. };
  235. }
  236. },
  237. fail: (e) => {
  238. console.log("获取签到信息失败:", e);
  239. }
  240. });
  241. },
  242. // 显示兑换弹窗
  243. showExchangePopup() {
  244. this.showExchange = true;
  245. },
  246. // 隐藏兑换弹窗
  247. hideExchangePopup() {
  248. this.showExchange = false;
  249. },
  250. // 显示签到弹窗
  251. showSignPopup() {
  252. this.showSign = true;
  253. },
  254. // 隐藏签到弹窗
  255. hideSignPopup() {
  256. this.showSign = false;
  257. },
  258. // 切换签到通知开关
  259. toggleSignNotify(e) {
  260. this.signNotify = e.detail.value;
  261. },
  262. // 确认签到
  263. confirmSign() {
  264. if(this.signInfo.isSigned) {
  265. uni.showToast({
  266. title: "今日已签到",
  267. icon: 'none'
  268. });
  269. return;
  270. }
  271. uni.request({
  272. url: this.$apiHost + '/User/sign7Day',
  273. data: {
  274. uuid: getApp().globalData.uuid,
  275. action: 'sign'
  276. },
  277. header: {
  278. "content-type": "application/json",
  279. 'sign': getApp().globalData.headerSign
  280. },
  281. success: (res) => {
  282. if(res.data.success === 'yes') {
  283. uni.showToast({
  284. title: res.data.str,
  285. icon: 'none'
  286. });
  287. // 更新签到信息
  288. this.getSignInfo();
  289. // 更新彩豆数量
  290. this.loadData();
  291. } else {
  292. uni.showToast({
  293. title: res.data.str,
  294. icon: 'none'
  295. });
  296. }
  297. },
  298. fail: (e) => {
  299. console.log("签到失败:", e);
  300. uni.showToast({
  301. title: "签到失败,请稍后重试",
  302. icon: 'none'
  303. });
  304. }
  305. });
  306. },
  307. // 确认兑换
  308. confirmExchange() {
  309. if (!this.exchangeAmount) {
  310. uni.showToast({
  311. title: "请输入兑换数量",
  312. icon: 'none'
  313. });
  314. return;
  315. }
  316. const amount = parseInt(this.exchangeAmount);
  317. if (isNaN(amount) || amount <= 0) {
  318. uni.showToast({
  319. title: "请输入有效数量",
  320. icon: 'none'
  321. });
  322. return;
  323. }
  324. if (amount % 10 !== 0) {
  325. uni.showToast({
  326. title: "兑换数量必须是10的倍数",
  327. icon: 'none'
  328. });
  329. return;
  330. }
  331. let that = this;
  332. uni.request({
  333. url: this.$apiHost + '/User/gmdToGMM',
  334. data: {
  335. uuid: getApp().globalData.uuid,
  336. num: amount
  337. },
  338. header: {
  339. "content-type": "application/json",
  340. 'sign': getApp().globalData.headerSign
  341. },
  342. success: (res) => {
  343. console.log("----:", res.data);
  344. uni.showToast({
  345. title: res.data.str,
  346. icon: 'none'
  347. });
  348. if (res.data.success == 'yes') {
  349. this.hideExchangePopup();
  350. this.exchangeAmount = '';
  351. setTimeout(function() {
  352. that.loadData();
  353. }, 900);
  354. }
  355. },
  356. complete: (com) => {
  357. // uni.hideLoading();
  358. },
  359. fail: (e) => {
  360. console.log("----e:", e);
  361. }
  362. });
  363. // // 模拟兑换处理
  364. // uni.showToast({
  365. // title: "兑换成功,获得" + amount + "彩豆",
  366. // icon: 'none'
  367. // });
  368. // this.beanBalance += amount;
  369. // this.hideExchangePopup();
  370. // this.exchangeAmount = '';
  371. },
  372. claimReward(index) {
  373. if (this.taskList[index].status == 9) {
  374. uni.showToast({
  375. title: "已领取该奖励",
  376. icon: 'none'
  377. });
  378. return;
  379. }
  380. let that = this;
  381. uni.request({
  382. url: this.$apiHost + '/Job/doAct',
  383. data: {
  384. uuid: getApp().globalData.uuid,
  385. id: this.taskList[index].id
  386. },
  387. header: {
  388. "content-type": "application/json",
  389. 'sign': getApp().globalData.headerSign
  390. },
  391. success: (res) => {
  392. console.log("----:", res.data);
  393. if (res.data.success == 'yes') {
  394. uni.showToast({
  395. title: res.data.str,
  396. icon: 'none'
  397. });
  398. setTimeout(function() {
  399. that.loadData();
  400. }, 900);
  401. }
  402. },
  403. complete: (com) => {
  404. // uni.hideLoading();
  405. },
  406. fail: (e) => {
  407. console.log("----e:", e);
  408. }
  409. });
  410. },
  411. }
  412. }
  413. </script>
  414. <style scoped lang="scss">
  415. @import 'job.scss';
  416. </style>