step.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  1. <template>
  2. <view class="step-container">
  3. <!-- 步骤指示器 -->
  4. <view class="step-header">
  5. <text class="step-title">STEP {{ currentStep }}</text>
  6. <view class="step-progress">
  7. <view class="progress-bar">
  8. <view class="progress-inner" :style="{ width: currentStep === 1 ? '50%' : '100%' }"></view>
  9. </view>
  10. </view>
  11. </view>
  12. <!-- 步骤1:个人信息 -->
  13. <view v-if="currentStep === 1" class="step-content">
  14. <view class="step-subtitle">定制个人信息</view>
  15. <!-- 头像上传 -->
  16. <view class="avatar-section">
  17. <view class="avatar-wrapper" @click="chooseAvatar">
  18. <image v-if="userInfo.avatar" :src="userInfo.avatar" mode="aspectFill" class="avatar"></image>
  19. <view v-else class="avatar-placeholder">
  20. <image src="/static/icons/camera.png" mode="aspectFit" class="camera-icon"></image>
  21. </view>
  22. </view>
  23. </view>
  24. <!-- 昵称输入 -->
  25. <view class="input-section">
  26. <view class="input-label">我的名字</view>
  27. <view class="input-wrapper">
  28. <input
  29. type="text"
  30. v-model="userInfo.nickname"
  31. placeholder="取一个独一无二的名字吧~"
  32. placeholder-class="input-placeholder"
  33. />
  34. <image
  35. v-if="userInfo.nickname"
  36. src="/static/icons/clear.png"
  37. mode="aspectFit"
  38. class="clear-icon"
  39. @click="userInfo.nickname = ''"
  40. ></image>
  41. </view>
  42. </view>
  43. <!-- 性别选择 -->
  44. <view class="gender-section">
  45. <view class="input-label">性别</view>
  46. <view class="gender-options">
  47. <view
  48. class="gender-item"
  49. :class="{ active: userInfo.gender === 'male' }"
  50. @click="userInfo.gender = 'male'"
  51. >
  52. <image src="/static/icons/male.png" mode="aspectFit" class="gender-icon"></image>
  53. <text>男生</text>
  54. </view>
  55. <view
  56. class="gender-item"
  57. :class="{ active: userInfo.gender === 'female' }"
  58. @click="userInfo.gender = 'female'"
  59. >
  60. <image src="/static/icons/female.png" mode="aspectFit" class="gender-icon"></image>
  61. <text>女生</text>
  62. </view>
  63. <view
  64. class="gender-item"
  65. :class="{ active: userInfo.gender === 'other' }"
  66. @click="userInfo.gender = 'other'"
  67. >
  68. <image src="/static/icons/other.png" mode="aspectFit" class="gender-icon"></image>
  69. <text>其他</text>
  70. </view>
  71. </view>
  72. </view>
  73. <!-- 生日选择 -->
  74. <view class="birthday-section">
  75. <view class="input-label">我的生日</view>
  76. <view class="birthday-picker" @click="showDatePicker = true">
  77. <text :class="{ placeholder: !userInfo.birthday }">{{ userInfo.birthday || '告诉我你的生日吧' }}</text>
  78. <image src="/static/icons/arrow-right.png" mode="aspectFit" class="arrow-icon"></image>
  79. </view>
  80. </view>
  81. </view>
  82. <!-- 步骤2:兴趣选择 -->
  83. <view v-if="currentStep === 2" class="step-content">
  84. <view class="step-subtitle">定制个人兴趣圈</view>
  85. <view class="interest-section">
  86. <text class="interest-tip">请选择</text>
  87. <!-- 兴趣选择圆圈 -->
  88. <view class="interest-circles">
  89. <view
  90. v-for="(interest, index) in interests"
  91. :key="index"
  92. class="interest-circle"
  93. :class="{ active: selectedInterests.includes(interest.id) }"
  94. @click="toggleInterest(interest.id)"
  95. >
  96. {{ interest.name }}
  97. </view>
  98. </view>
  99. <!-- 添加兴趣爱好 -->
  100. <view class="add-interests">
  101. <text class="add-title">添加兴趣爱好</text>
  102. <view class="interest-tags">
  103. <view
  104. v-for="(tag, index) in interestTags"
  105. :key="index"
  106. class="interest-tag"
  107. :class="{ active: selectedTags.includes(tag.id) }"
  108. @click="toggleTag(tag.id)"
  109. >
  110. {{ tag.name }}
  111. <text v-if="selectedTags.includes(tag.id)" class="remove-tag" @click.stop="removeTag(tag.id)">×</text>
  112. </view>
  113. <view class="add-tag" @click="showAddTag = true">
  114. <image src="/static/icons/add.png" mode="aspectFit" class="add-icon"></image>
  115. 创建新偏好
  116. </view>
  117. </view>
  118. </view>
  119. </view>
  120. </view>
  121. <!-- 底部按钮 -->
  122. <view class="bottom-button" :class="{ 'step2': currentStep === 2 }" @click="handleNext">
  123. {{ currentStep === 1 ? '下一步' : '完成' }}
  124. </view>
  125. <!-- 日期选择弹窗 -->
  126. <uni-datetime-picker
  127. v-if="showDatePicker"
  128. type="date"
  129. :value="userInfo.birthday"
  130. @confirm="onDateConfirm"
  131. @close="showDatePicker = false"
  132. />
  133. <!-- 添加标签弹窗 -->
  134. <uni-popup v-if="showAddTag" @close="showAddTag = false">
  135. <view class="add-tag-popup">
  136. <input
  137. type="text"
  138. v-model="newTag"
  139. placeholder="请输入新的兴趣爱好"
  140. @confirm="addNewTag"
  141. />
  142. <button @click="addNewTag">添加</button>
  143. </view>
  144. </uni-popup>
  145. </view>
  146. </template>
  147. <script>
  148. import {
  149. requestAndroidPermission,
  150. gotoAppPermissionSetting
  151. } from '../index/permission.js'
  152. export default {
  153. components: {},
  154. data() {
  155. return {
  156. showRights: false,
  157. title: '',
  158. currentStep: 1,
  159. sel: 1,
  160. info: {},
  161. showPop: false,
  162. nickname: '',
  163. wechat: '',
  164. sex: 1,
  165. age: 18,
  166. height: 160,
  167. weight: 50,
  168. avator: '../../static/me/avator.png',
  169. ziye: '',
  170. qianmin: '',
  171. xueli_sel: '',
  172. xueli: ['初中', '初中', '中专', '高中', '专科', '本科', '研究生', '硕士', '博士'],
  173. xinzuo_sel: '',
  174. xinzuo: ['水瓶座', '双鱼座', '白羊座', '金牛座', '双子座', '巨蟹座', '狮子座', '处女座', '天秤座', '天蝎座', '射手座', '摩羯座'],
  175. list_tag: [
  176. '篮球', '排球', '足球', '羽毛球', '健身达人', '美食达人'
  177. ],
  178. sel_tags: [],
  179. selectedTags: [],
  180. tagList: [
  181. { name: '游戏', size: 'large' },
  182. { name: '音乐', size: 'medium' },
  183. { name: '盲盒', size: 'large' },
  184. { name: '小可爱', size: 'small' },
  185. { name: '娃娃人', size: 'medium' },
  186. { name: '纹身', size: 'large' },
  187. { name: '洛丽塔', size: 'small' },
  188. { name: '女装', size: 'medium' },
  189. { name: '萌球', size: 'small' }
  190. ],
  191. userInfo: {
  192. avatar: '',
  193. nickname: '',
  194. gender: '',
  195. birthday: ''
  196. },
  197. interests: [
  198. { id: 1, name: '电影' },
  199. { id: 2, name: '宠物' },
  200. { id: 3, name: 'Hip-Hop' },
  201. { id: 4, name: '旅行' },
  202. { id: 5, name: '潮玩' },
  203. { id: 6, name: '运动' },
  204. { id: 7, name: '游戏' },
  205. { id: 8, name: '二次元' }
  206. ],
  207. selectedInterests: [],
  208. interestTags: [
  209. { id: 1, name: 'ACG' },
  210. { id: 2, name: '明日方舟' },
  211. { id: 3, name: '手游深度玩家' },
  212. { id: 4, name: '游戏人生' },
  213. { id: 5, name: '碧蓝档案' },
  214. { id: 6, name: '夏目友人帐' },
  215. { id: 7, name: 'FATE' }
  216. ],
  217. showDatePicker: false,
  218. showAddTag: false,
  219. newTag: ''
  220. }
  221. },
  222. onLoad() {
  223. this.currentStep = 1;
  224. let tagStr =
  225. "篮球、羽毛球、兵乓球、足球、滑板、滑旱冰、跑步、跳绳、举重、听音乐、看电影、绘画、写小说、看书、做弹弓玩、做木剑玩、做橡皮枪玩、积木、用麻将搭金字塔、拼图、拆装、扑克牌、小汽车、手表、鞋之类的、弹吉他、钢琴、萨克斯、葫芦丝、大号、小号、折纸、剪纸、品茶、涂鸦、英雄联盟、qq堂、cs、cf、地下城勇士、桌面游戏";
  226. this.list_tag = tagStr.split("、");
  227. this.getInfoData();
  228. },
  229. onShow() {},
  230. methods: {
  231. onBack() {},
  232. chkSel() {
  233. if (this.sel == 1) {
  234. this.sel = 0;
  235. } else {
  236. this.sel = 1;
  237. }
  238. },
  239. chkSex(sex) {
  240. this.sex = sex;
  241. },
  242. delTag(tg) {
  243. let list_tag2 = [];
  244. for (let i = 0; i < this.sel_tags.length; i++) {
  245. if (this.sel_tags[i] != tg && this.sel_tags[i] != '') {
  246. list_tag2.push(this.sel_tags[i]);
  247. }
  248. }
  249. this.sel_tags = list_tag2;
  250. },
  251. selTags(itm) {
  252. let that = this;
  253. let isIn = false;
  254. for (let entry of this.sel_tags) {
  255. // console.log(entry); // 1, "string", false
  256. if (entry == itm) {
  257. isIn = true;
  258. break;
  259. }
  260. }
  261. return isIn;
  262. },
  263. chkTag(itm) {
  264. if (this.selTags(itm)) {
  265. let tmpTags = [];
  266. for (let entry of this.sel_tags) {
  267. // console.log(entry); // 1, "string", false
  268. if (entry != itm && entry != '') {
  269. tmpTags.push(entry);
  270. }
  271. }
  272. this.sel_tags = tmpTags;
  273. } else {
  274. if (this.sel_tags.length >= 10) {
  275. this.$refs['ToastW3'].showToast({
  276. title: "最多选择10个标签",
  277. animation: 0
  278. });
  279. return;
  280. }
  281. this.sel_tags.push(itm);
  282. }
  283. },
  284. sliderChange1(e) {
  285. this.age = e.detail.value;
  286. },
  287. sliderChange2(e) {
  288. this.height = e.detail.value;
  289. },
  290. sliderChange3(e) {
  291. this.weight = e.detail.value;
  292. },
  293. SetXueli() {
  294. let that = this;
  295. uni.showActionSheet({
  296. itemColor: '#000000',
  297. itemList: this.xueli,
  298. success: function(res) {
  299. that.xueli_sel = that.xueli[res.tapIndex];
  300. // console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
  301. },
  302. fail: function(res) {
  303. console.log(res.errMsg);
  304. }
  305. });
  306. },
  307. SetXinzuo() {
  308. let that = this;
  309. uni.showActionSheet({
  310. itemColor: '#000000',
  311. itemList: this.xinzuo,
  312. success: function(res) {
  313. that.xinzuo_sel = that.xinzuo[res.tapIndex];
  314. // console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
  315. },
  316. fail: function(res) {
  317. console.log(res.errMsg);
  318. }
  319. });
  320. },
  321. getInfoData() {
  322. console.log(this.$apiHost + '/Member/getinfoData');
  323. uni.request({
  324. url: this.$apiHost + '/Member/getinfoData', //仅为示例,并非真实接口地址。
  325. data: {
  326. uuid: getApp().globalData.uuid
  327. },
  328. header: {
  329. 'content-type': 'application/json' //自定义请求头信息
  330. },
  331. success: (res) => {
  332. console.log("res", res.data)
  333. this.nickname = res.data.nickname;
  334. this.wechat = res.data.wechat;
  335. this.sex = res.data.sex || 2;
  336. this.age = res.data.age || 18;
  337. this.height = res.data.height || 160;
  338. this.weight = res.data.weight || 50;
  339. this.xueli_sel = res.data.xueli;
  340. this.xinzuo_sel = res.data.xinzuo;
  341. this.ziye = res.data.ziye;
  342. this.qianmin = res.data.qianmin;
  343. if (res.data.avator != "") {
  344. this.avator = res.data.avator;
  345. }
  346. if (res.data.aihao != null && res.data.aihao != undefined) {
  347. if (res.data.aihao.length > 0) {
  348. this.sel_tags = res.data.aihao.split(",");
  349. }
  350. }
  351. }
  352. });
  353. },
  354. submitData() {
  355. let aihao = this.sel_tags.join(',')
  356. let obj2 = {
  357. uuid: getApp().globalData.uuid,
  358. avator: this.avator,
  359. nickname: this.nickname,
  360. wechat: this.wechat,
  361. sex: this.sex,
  362. age: this.age,
  363. height: this.height,
  364. weight: this.weight,
  365. xueli: this.xueli_sel,
  366. xinzuo: this.xinzuo_sel,
  367. ziye: this.ziye,
  368. qianmin: this.qianmin,
  369. aihao: aihao
  370. }
  371. // console.log("obj2", obj2);
  372. uni.request({
  373. url: this.$apiHost + '/Member/setinfoData', //仅为示例,并非真实接口地址。
  374. data: obj2,
  375. method: 'POST',
  376. header: {
  377. 'Content-Type': 'application/x-www-form-urlencoded',
  378. 'sign': getApp().globalData.headerSign
  379. },
  380. dataType: 'json',
  381. // header: {
  382. // 'content-type': 'application/json', //自定义请求头信息
  383. // 'Access-Control-Allow-Origin': '*'
  384. // },
  385. success: (res) => {
  386. console.log("res", res.data)
  387. this.$refs['ToastW3'].showToast({
  388. title: res.data.str,
  389. animation: 0
  390. });
  391. if (res.data.success == "yes") {
  392. uni.switchTab({
  393. url: "/pages/index/index",
  394. });
  395. }
  396. }
  397. });
  398. },
  399. // upload() {
  400. // let that = this;
  401. // this.$refs['DialogBox'].confirm({
  402. // title: '提示',
  403. // content: '该权限用于获取设备拍摄或获取本地应用相册,进行头像的图片上传。',
  404. // DialogType: 'inquiry',
  405. // btn1: '拒绝',
  406. // btn2: '同意',
  407. // animation: 0
  408. // }).then((res) => {
  409. // that.upload2();
  410. // })
  411. // },
  412. upload() {
  413. this.checkRights();
  414. console.log("----upload");
  415. var _self = this;
  416. uni.chooseImage({
  417. count: 1,
  418. sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有
  419. sourceType: ['album', 'camera'], //从相册、相机选择
  420. extension: ['.png', '.jpeg', '.jpg'],
  421. success: function(res) {
  422. console.log('res:', res)
  423. _self.imglocal = res.tempFilePaths[0]
  424. const tempFilePaths = res.tempFilePaths[0];
  425. console.log('tempFilePaths:', tempFilePaths);
  426. // 图片上传
  427. const uploadTask = uni.uploadFile({
  428. url: _self.$apiHost + '/Xweb/upload_img?skey=' + _self.skey, // post请求地址
  429. filePath: res.tempFilePaths[0],
  430. name: 'file', // 待确认
  431. success: function(uploadFileRes) {
  432. let resdata = JSON.parse(uploadFileRes.data)
  433. console.log('Success11:', uploadFileRes);
  434. console.log('Success21:', resdata);
  435. if (resdata.success == 'yes') {
  436. _self.avator = resdata.url;
  437. }
  438. },
  439. fail: function(uploadFileFail) {
  440. console.log('Error:', uploadFileFail.data);
  441. },
  442. complete: () => {
  443. console.log('Complete:');
  444. }
  445. });
  446. },
  447. error: function(e) {
  448. console.log(e);
  449. }
  450. });
  451. },
  452. checkRights() {
  453. let that = this;
  454. that.showRights = true;
  455. requestAndroidPermission('android.permission.CAMERA')
  456. .then(result => {
  457. that.showRights = false;
  458. // 根据返回的结果进行处理
  459. if (result === 1) {} else if (result === 0) {
  460. console.log('权限被拒绝');
  461. } else if (result === -1) {
  462. console.log('权限被永久拒绝');
  463. }
  464. })
  465. .catch(error => {
  466. that.showRights = true;
  467. console.log('权限申请失败:', error);
  468. });
  469. },
  470. selectTag(index) {
  471. const tagIndex = this.selectedTags.indexOf(index);
  472. if (tagIndex === -1) {
  473. // 如果未选中,则添加到选中数组
  474. this.selectedTags.push(index);
  475. } else {
  476. // 如果已选中,则从数组中移除
  477. this.selectedTags.splice(tagIndex, 1);
  478. }
  479. },
  480. chooseAvatar() {
  481. uni.chooseImage({
  482. count: 1,
  483. sizeType: ['compressed'],
  484. sourceType: ['album', 'camera'],
  485. success: (res) => {
  486. this.userInfo.avatar = res.tempFilePaths[0]
  487. }
  488. })
  489. },
  490. toggleInterest(id) {
  491. const index = this.selectedInterests.indexOf(id)
  492. if (index === -1) {
  493. this.selectedInterests.push(id)
  494. } else {
  495. this.selectedInterests.splice(index, 1)
  496. }
  497. },
  498. toggleTag(id) {
  499. const index = this.selectedTags.indexOf(id)
  500. if (index === -1) {
  501. this.selectedTags.push(id)
  502. } else {
  503. this.selectedTags.splice(index, 1)
  504. }
  505. },
  506. removeTag(id) {
  507. const index = this.selectedTags.indexOf(id)
  508. if (index !== -1) {
  509. this.selectedTags.splice(index, 1)
  510. }
  511. },
  512. addNewTag() {
  513. if (this.newTag.trim()) {
  514. const newId = this.interestTags.length + 1
  515. this.interestTags.push({
  516. id: newId,
  517. name: this.newTag.trim()
  518. })
  519. this.selectedTags.push(newId)
  520. this.newTag = ''
  521. this.showAddTag = false
  522. }
  523. },
  524. onDateConfirm(date) {
  525. this.userInfo.birthday = this.$u.timeFormat(date, 'yyyy-mm-dd')
  526. this.showDatePicker = false
  527. },
  528. handleNext() {
  529. if (this.currentStep === 1) {
  530. // 验证第一步数据
  531. if (!this.userInfo.nickname) {
  532. uni.showToast({
  533. title: '请输入昵称',
  534. icon: 'none'
  535. })
  536. return
  537. }
  538. if (!this.userInfo.gender) {
  539. uni.showToast({
  540. title: '请选择性别',
  541. icon: 'none'
  542. })
  543. return
  544. }
  545. this.currentStep = 2
  546. } else {
  547. // 验证第二步数据
  548. if (this.selectedInterests.length === 0 && this.selectedTags.length === 0) {
  549. uni.showToast({
  550. title: '请至少选择一个兴趣',
  551. icon: 'none'
  552. })
  553. return
  554. }
  555. // 提交所有数据
  556. this.submitUserInfo()
  557. }
  558. },
  559. submitUserInfo() {
  560. const data = {
  561. ...this.userInfo,
  562. interests: this.selectedInterests,
  563. tags: this.selectedTags
  564. }
  565. uni.showLoading({
  566. title: '保存中...'
  567. })
  568. // 调用API保存用户信息
  569. uni.request({
  570. url: this.$apiHost + '/user/updateProfile',
  571. method: 'POST',
  572. data: data,
  573. header: {
  574. 'content-type': 'application/json',
  575. 'sign': getApp().globalData.headerSign
  576. },
  577. success: (res) => {
  578. if (res.data.success === 'yes') {
  579. uni.showToast({
  580. title: '保存成功',
  581. icon: 'success'
  582. })
  583. // 延迟跳转
  584. setTimeout(() => {
  585. uni.switchTab({
  586. url: '/pages/index/index'
  587. })
  588. }, 1500)
  589. } else {
  590. uni.showToast({
  591. title: res.data.msg || '保存失败',
  592. icon: 'none'
  593. })
  594. }
  595. },
  596. fail: () => {
  597. uni.showToast({
  598. title: '网络错误',
  599. icon: 'none'
  600. })
  601. },
  602. complete: () => {
  603. uni.hideLoading()
  604. }
  605. })
  606. }
  607. }
  608. }
  609. </script>
  610. <style lang="scss">
  611. @import 'normal.scss';
  612. .popSel {
  613. position: fixed;
  614. z-index: 999999;
  615. top: 0;
  616. left: 0;
  617. background-color: #121212;
  618. width: 100vh;
  619. height: 100vh;
  620. }
  621. .tag_all_select {
  622. padding: 20rpx;
  623. .tag_items {
  624. display: flex;
  625. flex-wrap: wrap;
  626. gap: 30rpx;
  627. justify-content: center;
  628. align-items: center;
  629. .tag_item {
  630. display: flex;
  631. align-items: center;
  632. justify-content: center;
  633. border-radius: 50%;
  634. background: rgba(255,255,255,0.1);
  635. color: #fff;
  636. font-size: 26rpx;
  637. transition: all 0.3s ease;
  638. cursor: pointer;
  639. &.small {
  640. width: 120rpx;
  641. height: 120rpx;
  642. }
  643. &.medium {
  644. width: 160rpx;
  645. height: 160rpx;
  646. font-size: 28rpx;
  647. }
  648. &.large {
  649. width: 200rpx;
  650. height: 200rpx;
  651. font-size: 32rpx;
  652. }
  653. &.active {
  654. transform: scale(1.2);
  655. background: rgba(255,255,255,0.2);
  656. box-shadow: 0 0 20rpx rgba(255,255,255,0.3);
  657. z-index: 1;
  658. }
  659. &:not(.active):hover {
  660. transform: scale(1.05);
  661. }
  662. }
  663. }
  664. }
  665. .step-container {
  666. min-height: 100vh;
  667. background: #fff;
  668. padding: 60rpx 40rpx;
  669. box-sizing: border-box;
  670. }
  671. .step-header {
  672. margin-bottom: 60rpx;
  673. .step-title {
  674. font-size: 48rpx;
  675. font-weight: bold;
  676. color: #000;
  677. margin-bottom: 20rpx;
  678. }
  679. .step-progress {
  680. height: 6rpx;
  681. background: #F1F1F1;
  682. border-radius: 3rpx;
  683. .progress-inner {
  684. height: 100%;
  685. background: #000;
  686. border-radius: 3rpx;
  687. transition: width 0.3s;
  688. }
  689. }
  690. }
  691. .step-content {
  692. .step-subtitle {
  693. font-size: 36rpx;
  694. font-weight: bold;
  695. color: #000;
  696. margin-bottom: 40rpx;
  697. }
  698. }
  699. .avatar-section {
  700. display: flex;
  701. justify-content: center;
  702. margin-bottom: 60rpx;
  703. .avatar-wrapper {
  704. width: 180rpx;
  705. height: 180rpx;
  706. border-radius: 50%;
  707. overflow: hidden;
  708. background: #F8F8F8;
  709. display: flex;
  710. align-items: center;
  711. justify-content: center;
  712. .avatar {
  713. width: 100%;
  714. height: 100%;
  715. }
  716. .avatar-placeholder {
  717. width: 60rpx;
  718. height: 60rpx;
  719. .camera-icon {
  720. width: 100%;
  721. height: 100%;
  722. }
  723. }
  724. }
  725. }
  726. .input-section {
  727. margin-bottom: 40rpx;
  728. .input-label {
  729. font-size: 28rpx;
  730. color: #666;
  731. margin-bottom: 20rpx;
  732. }
  733. .input-wrapper {
  734. position: relative;
  735. input {
  736. width: 100%;
  737. height: 88rpx;
  738. background: #F8F8F8;
  739. border-radius: 44rpx;
  740. padding: 0 30rpx;
  741. font-size: 28rpx;
  742. }
  743. .clear-icon {
  744. position: absolute;
  745. right: 30rpx;
  746. top: 50%;
  747. transform: translateY(-50%);
  748. width: 32rpx;
  749. height: 32rpx;
  750. }
  751. }
  752. }
  753. .gender-section {
  754. margin-bottom: 40rpx;
  755. .gender-options {
  756. display: flex;
  757. justify-content: space-between;
  758. .gender-item {
  759. flex: 1;
  760. height: 160rpx;
  761. background: #F8F8F8;
  762. border-radius: 20rpx;
  763. margin: 0 10rpx;
  764. display: flex;
  765. flex-direction: column;
  766. align-items: center;
  767. justify-content: center;
  768. &.active {
  769. background: #E8FFD5;
  770. }
  771. .gender-icon {
  772. width: 60rpx;
  773. height: 60rpx;
  774. margin-bottom: 10rpx;
  775. }
  776. text {
  777. font-size: 24rpx;
  778. color: #333;
  779. }
  780. }
  781. }
  782. }
  783. .interest-section {
  784. .interest-tip {
  785. font-size: 28rpx;
  786. color: #666;
  787. margin-bottom: 30rpx;
  788. }
  789. .interest-circles {
  790. display: flex;
  791. flex-wrap: wrap;
  792. gap: 20rpx;
  793. margin-bottom: 60rpx;
  794. .interest-circle {
  795. width: 140rpx;
  796. height: 140rpx;
  797. border-radius: 50%;
  798. background: #F8F8F8;
  799. display: flex;
  800. align-items: center;
  801. justify-content: center;
  802. font-size: 28rpx;
  803. color: #333;
  804. &.active {
  805. background: #ACF934;
  806. color: #000;
  807. }
  808. }
  809. }
  810. }
  811. .interest-tags {
  812. display: flex;
  813. flex-wrap: wrap;
  814. gap: 20rpx;
  815. .interest-tag {
  816. padding: 16rpx 30rpx;
  817. background: #F8F8F8;
  818. border-radius: 30rpx;
  819. font-size: 28rpx;
  820. color: #333;
  821. display: flex;
  822. align-items: center;
  823. &.active {
  824. background: #ACF934;
  825. color: #000;
  826. }
  827. .remove-tag {
  828. margin-left: 10rpx;
  829. font-size: 32rpx;
  830. }
  831. }
  832. .add-tag {
  833. padding: 16rpx 30rpx;
  834. background: #F8F8F8;
  835. border-radius: 30rpx;
  836. font-size: 28rpx;
  837. color: #666;
  838. display: flex;
  839. align-items: center;
  840. .add-icon {
  841. width: 32rpx;
  842. height: 32rpx;
  843. margin-right: 10rpx;
  844. }
  845. }
  846. }
  847. .bottom-button {
  848. position: fixed;
  849. left: 40rpx;
  850. right: 40rpx;
  851. bottom: 40rpx;
  852. height: 88rpx;
  853. background: #000;
  854. border-radius: 44rpx;
  855. color: #fff;
  856. font-size: 32rpx;
  857. display: flex;
  858. align-items: center;
  859. justify-content: center;
  860. &.step2 {
  861. background: #ACF934;
  862. color: #000;
  863. }
  864. }
  865. </style>