job.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  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"
  109. v-if="index < signInfo.signDay || (index === signInfo.signDay - 1 && signInfo.isSigned)">
  110. <text class="received-text">已领取</text>
  111. </view>
  112. </view>
  113. </view>
  114. <!-- 底部签到按钮 -->
  115. <view class="sign-btn-large" :class="{'sign-btn-disabled': signInfo.isSigned}" @click="confirmSign">
  116. {{signInfo.isSigned ? '今日已签到' : '签到领取奖励'}}
  117. </view>
  118. </view>
  119. </view>
  120. <!-- 提示框 -->
  121. <DialogBox ref="DialogBox"></DialogBox>
  122. </view>
  123. </template>
  124. <script>
  125. export default {
  126. components: {},
  127. data() {
  128. return {
  129. title: '任务中心',
  130. myinfo: {},
  131. realname: '',
  132. num_gmd: 0,
  133. newer_bfb: '',
  134. beanBalance: 2560,
  135. showExchange: false,
  136. exchangeAmount: '',
  137. mCoinBalance: 14500,
  138. showSign: false,
  139. signNotify: true,
  140. signRewards: [{
  141. dayNum: '01',
  142. reward: '10彩豆',
  143. isVip: false
  144. },
  145. {
  146. dayNum: '02',
  147. reward: '15彩豆',
  148. isVip: false
  149. },
  150. {
  151. dayNum: '03',
  152. reward: '20彩豆',
  153. isVip: false
  154. },
  155. {
  156. dayNum: '04',
  157. reward: '25彩豆',
  158. isVip: false
  159. },
  160. {
  161. dayNum: '05',
  162. reward: '30彩豆',
  163. isVip: false
  164. },
  165. {
  166. dayNum: '06',
  167. reward: '35彩豆',
  168. isVip: true
  169. },
  170. {
  171. dayNum: '07',
  172. reward: '50彩豆',
  173. isVip: true
  174. }
  175. ],
  176. signInfo: {
  177. signDay: 1,
  178. isSigned: false,
  179. reward: 0
  180. },
  181. taskList: []
  182. }
  183. },
  184. onLoad() {
  185. this.loadData();
  186. this.getSignInfo();
  187. },
  188. onShow() {},
  189. methods: {
  190. onBack() {},
  191. loadData() {
  192. uni.request({
  193. url: this.$apiHost + '/Job/getlist',
  194. data: {
  195. uuid: getApp().globalData.uuid
  196. },
  197. header: {
  198. "content-type": "application/json",
  199. 'sign': getApp().globalData.headerSign
  200. },
  201. success: (res) => {
  202. console.log("----:", res.data);
  203. this.num_gmd = res.data.num_gmd;
  204. this.newer_bfb = res.data.newer_bfb;
  205. this.taskList = res.data.list;
  206. },
  207. complete: (com) => {
  208. // uni.hideLoading();
  209. },
  210. fail: (e) => {
  211. console.log("----e:", e);
  212. }
  213. });
  214. },
  215. // 获取签到信息
  216. getSignInfo() {
  217. uni.request({
  218. url: this.$apiHost + '/User/sign7Day',
  219. data: {
  220. uuid: getApp().globalData.uuid,
  221. action: 'get'
  222. },
  223. header: {
  224. "content-type": "application/json",
  225. 'sign': getApp().globalData.headerSign
  226. },
  227. success: (res) => {
  228. if (res.data.success === 'yes') {
  229. this.signInfo = {
  230. signDay: res.data.data.sign_day,
  231. isSigned: res.data.data.is_signed,
  232. reward: res.data.data.reward || 0
  233. };
  234. }
  235. },
  236. fail: (e) => {
  237. console.log("获取签到信息失败:", e);
  238. }
  239. });
  240. },
  241. // 显示兑换弹窗
  242. showExchangePopup() {
  243. this.showExchange = true;
  244. },
  245. // 隐藏兑换弹窗
  246. hideExchangePopup() {
  247. this.showExchange = false;
  248. },
  249. // 显示签到弹窗
  250. showSignPopup() {
  251. this.showSign = true;
  252. },
  253. // 隐藏签到弹窗
  254. hideSignPopup() {
  255. this.showSign = false;
  256. },
  257. // 切换签到通知开关
  258. toggleSignNotify(e) {
  259. this.signNotify = e.detail.value;
  260. },
  261. // 确认签到
  262. confirmSign() {
  263. if (this.signInfo.isSigned) {
  264. uni.showToast({
  265. title: "今日已签到",
  266. icon: 'none'
  267. });
  268. return;
  269. }
  270. uni.request({
  271. url: this.$apiHost + '/User/sign7Day',
  272. data: {
  273. uuid: getApp().globalData.uuid,
  274. action: 'sign'
  275. },
  276. header: {
  277. "content-type": "application/json",
  278. 'sign': getApp().globalData.headerSign
  279. },
  280. success: (res) => {
  281. if (res.data.success === 'yes') {
  282. uni.showToast({
  283. title: res.data.str,
  284. icon: 'none'
  285. });
  286. // 更新签到信息
  287. this.getSignInfo();
  288. // 更新彩豆数量
  289. this.loadData();
  290. } else {
  291. uni.showToast({
  292. title: res.data.str,
  293. icon: 'none'
  294. });
  295. }
  296. },
  297. fail: (e) => {
  298. console.log("签到失败:", e);
  299. uni.showToast({
  300. title: "签到失败,请稍后重试",
  301. icon: 'none'
  302. });
  303. }
  304. });
  305. },
  306. // 确认兑换
  307. confirmExchange() {
  308. if (!this.exchangeAmount) {
  309. uni.showToast({
  310. title: "请输入兑换数量",
  311. icon: 'none'
  312. });
  313. return;
  314. }
  315. const amount = parseInt(this.exchangeAmount);
  316. if (isNaN(amount) || amount <= 0) {
  317. uni.showToast({
  318. title: "请输入有效数量",
  319. icon: 'none'
  320. });
  321. return;
  322. }
  323. if (amount % 10 !== 0) {
  324. uni.showToast({
  325. title: "兑换数量必须是10的倍数",
  326. icon: 'none'
  327. });
  328. return;
  329. }
  330. let that = this;
  331. uni.request({
  332. url: this.$apiHost + '/User/gmmToGMD',
  333. data: {
  334. uuid: getApp().globalData.uuid,
  335. num: amount
  336. },
  337. header: {
  338. "content-type": "application/json",
  339. 'sign': getApp().globalData.headerSign
  340. },
  341. success: (res) => {
  342. console.log("----:", res.data);
  343. uni.showToast({
  344. title: res.data.str,
  345. icon: 'none'
  346. });
  347. if (res.data.success == 'yes') {
  348. this.hideExchangePopup();
  349. this.exchangeAmount = '';
  350. setTimeout(function() {
  351. that.loadData();
  352. }, 900);
  353. }
  354. },
  355. complete: (com) => {
  356. // uni.hideLoading();
  357. },
  358. fail: (e) => {
  359. console.log("----e:", e);
  360. }
  361. });
  362. // // 模拟兑换处理
  363. // uni.showToast({
  364. // title: "兑换成功,获得" + amount + "彩豆",
  365. // icon: 'none'
  366. // });
  367. // this.beanBalance += amount;
  368. // this.hideExchangePopup();
  369. // this.exchangeAmount = '';
  370. },
  371. claimReward(index) {
  372. if (this.taskList[index].status == 9) {
  373. uni.showToast({
  374. title: "已领取该奖励",
  375. icon: 'none'
  376. });
  377. return;
  378. }
  379. let that = this;
  380. uni.request({
  381. url: this.$apiHost + '/Job/doAct',
  382. data: {
  383. uuid: getApp().globalData.uuid,
  384. id: this.taskList[index].id
  385. },
  386. header: {
  387. "content-type": "application/json",
  388. 'sign': getApp().globalData.headerSign
  389. },
  390. success: (res) => {
  391. console.log("----:", res.data);
  392. if (res.data.success == 'yes') {
  393. uni.showToast({
  394. title: res.data.str,
  395. icon: 'none'
  396. });
  397. setTimeout(function() {
  398. that.loadData();
  399. }, 900);
  400. }
  401. },
  402. complete: (com) => {
  403. // uni.hideLoading();
  404. },
  405. fail: (e) => {
  406. console.log("----e:", e);
  407. }
  408. });
  409. },
  410. }
  411. }
  412. </script>
  413. <style scoped lang="scss">
  414. @import 'job.scss';
  415. </style>