myStar.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898
  1. <template>
  2. <view class="star-container">
  3. <PageHeader title="" class="PageHeader" v-if="state == 1">
  4. <template v-slot:center> </template>
  5. </PageHeader>
  6. <!-- 星灵基因重组仓弹窗 -->
  7. <view class="gender-popup" v-if="state == 0">
  8. <NicknamePopup :closeOnClickOverlay="false" title="星灵基因重组仓" subtitle="" class="openContentPopUpWindow"
  9. ref="openContentPopUpWindow" @close="goBack()">
  10. <template v-slot:content>
  11. <uv-textarea v-model="noteContent" maxlength="200" count autoHeight
  12. placeholder="可描述你想要重新赋予Ta的形象、性别、性格、身份、兴趣爱好等(不会展示给其他人,仅你自己知道),示例:有一头波浪状的橙色头发,喜欢运动的阳光男孩..."></uv-textarea>
  13. <view class="btn-box blick-btn-animation" @tap="confirmGender">创建星灵</view>
  14. </template>
  15. </NicknamePopup>
  16. </view>
  17. <!-- 加载动画区域 -->
  18. <view class="loading-area" v-if=" state == 2 || isLoading">
  19. <c-lottie ref="cLottieRef" :src='"/static/lottie/xingqiu.json"' class="icon-img" height="1624rpx"
  20. width="750rpx" :loop="true" ></c-lottie>
  21. </view>
  22. <!-- 角色展示页面 -->
  23. <view class="character-page" v-else-if="state == 1">
  24. <view class="character-container">
  25. <image :src="starInfo.image || ''" mode="widthFix" class="character-image">
  26. </image>
  27. </view>
  28. <view class="bottom-button" @tap="goToSetProfile"> 设置星灵简介 </view>
  29. </view>
  30. <!-- 表单页面 -->
  31. <view class="form-page" v-else-if="state == 4">
  32. <PageHeader title="设置星灵简介" class="PageHeader">
  33. <template v-slot:center> </template>
  34. </PageHeader>
  35. <view class="reserveASeat"></view>
  36. <form @submit="submitForm">
  37. <view class="form-group">
  38. <view class="label">
  39. <text class="required">*</text>
  40. <text>昵称</text>
  41. </view>
  42. <input class="input" v-model="formData.nickname" placeholder="给星灵取个名字"
  43. :class="{ error: showError && !formData.nickname }" />
  44. </view>
  45. <view class="form-group">
  46. <view class="label">性别</view>
  47. <view class="gender-options">
  48. <view class="gender-option" :class="sex == 'male' ? 'selected' : ''"
  49. @tap="selectGender('male')">
  50. <view class="gender-icon male">
  51. <image src="../../static/me/wd_icon_nan.png" mode="aspectFit"></image>
  52. 男性
  53. </view>
  54. </view>
  55. <view class="gender-option" :class="sex == 'female' ? 'selected' : ''"
  56. @tap="selectGender('female')">
  57. <view class="gender-icon female">
  58. <image src="../../static/me/wd_icon_nv.png" mode="aspectFit"></image>
  59. 女性
  60. </view>
  61. </view>
  62. <view class="gender-option" :class="sex == 'other' ? 'selected' : ''"
  63. @tap="selectGender('other')">
  64. <view class="gender-icon other">
  65. <image src="../../static/me/wd_icon_qita.png" mode="aspectFit"></image>
  66. 其它
  67. </view>
  68. </view>
  69. </view>
  70. </view>
  71. <view class="form-group">
  72. <view class="label">
  73. <text class="required">*</text>
  74. <text>人物简介</text>
  75. </view>
  76. <view class="textarea-container">
  77. <textarea class="textarea" v-model="formData.description"
  78. placeholder="填写这个角色的人物介绍,例如性格、身份、背景与历程..." :maxlength="500"
  79. :class="{ error: showError && !formData.description }" autoHeight />
  80. <text class="word-count">{{ formData.description.length }}/500</text>
  81. </view>
  82. </view>
  83. <view class="form-group">
  84. <view class="label">人物标签</view>
  85. <!-- <scroll-view class="tags-scroll" scroll-x="true" show-scrollbar="false">
  86. <view class="tags-container">
  87. <view class="tag" v-for="tag in predefinedTags" :key="tag">
  88. {{ tag }}
  89. </view>
  90. </view>
  91. </scroll-view> -->
  92. <view class="tags-container">
  93. <!-- <view class="tag" :class="{ active: tagSet.has(tag) }" v-for="tag in predefinedTags" :key="tag"
  94. @tap="switchTag(tag)">
  95. {{ tag }}
  96. </view> -->
  97. <uni-data-checkbox mode="tag" multiple v-model="selectTags"
  98. :localdata="predefinedTags"></uni-data-checkbox>
  99. </view>
  100. </view>
  101. </form>
  102. <view class="submit-button" @tap="submitStar"> 确定并提交 </view>
  103. </view>
  104. <!-- 角色信息展示页面 -->
  105. <view class="character-info" v-else-if="state == 5 || state == 6">
  106. <view class="custom-navbar">
  107. <view class="navbar-left" @click="goBack">
  108. <text class="fa fa-angle-left" style="color: #000;"></text>
  109. </view>
  110. <view class="navbar-right" @click="showShare = true">
  111. <image src="@/static/icon/more2.png" style="width: 64rpx;height: 64rpx; margin-top: 15rpx;" mode="widthFix"></image>
  112. </view>
  113. </view>
  114. <view class="info-container">
  115. <!-- 角色立绘区域 -->
  116. <view class="character-portrait">
  117. <image :src="starInfo.image" mode="widthFix" class="portrait-image"></image>
  118. </view>
  119. <!-- 角色信息板块 -->
  120. <view class="info-section">
  121. <view class="character-name">
  122. <uv-input v-if="state == 5" v-model="starInfo.nickname" placeholder="请输入昵称" border="none" />
  123. <text v-else>{{ starInfo.nickname }}</text>
  124. <image class="male" v-if="starInfo.sex_id == 1" src="../../static/me/wd_icon_nan.png"
  125. mode="aspectFit">
  126. </image>
  127. <image class="female" v-else-if="starInfo.sex_id == 2" src="../../static/me/wd_icon_nv.png"
  128. mode="aspectFit">
  129. </image>
  130. <image class="other" v-else-if="starInfo.sex_id == 3" src="../../static/me/wd_icon_qita.png"
  131. mode="aspectFit"></image>
  132. </view>
  133. <!-- 人物简介 -->
  134. <view class="description-box">
  135. <view class="description-title">
  136. <view>Ta的设定</view>
  137. <view v-if="state == 5" class="edit-button" @click="showEditPopup">
  138. 编辑<text class="fa fa-angle-right" style="color: #000;"></text>
  139. </view>
  140. </view>
  141. <view class="description-text">
  142. <text>{{ starInfo.content }}</text>
  143. </view>
  144. </view>
  145. <!-- 标签展示 -->
  146. <view class="description-box">
  147. <view class="description-title">
  148. <view>人物标签</view>
  149. </view>
  150. <view class="tags-box">
  151. <view class="tag-item" v-for="tag in starInfo.tags" :key="tag">
  152. {{ tag }}
  153. </view>
  154. </view>
  155. </view>
  156. </view>
  157. </view>
  158. <!-- 底部按钮 -->
  159. <view class="join-button blick-btn-animation" @tap="handleJoin(1)" v-if="state == 5"> 入驻星球 </view>
  160. <view class="join-button blick-btn-animation" @tap="handleJoin(0)" v-if="state == 6"> 已入驻星球(点击进入星球) </view>
  161. </view>
  162. <!-- 编辑弹窗 -->
  163. <uni-popup ref="editPopup" type="center">
  164. <view class="edit-popup">
  165. <view class="popup-title">修改设定</view>
  166. <view class="popup-content">
  167. <uv-textarea v-model="editContent" :maxlength="500" count autoHeight placeholder="输入Ta的设定"
  168. class="edit-textarea" />
  169. </view>
  170. <view class="popup-buttons">
  171. <view class="cancel-btn" @click="closeEditPopup">再考虑一下</view>
  172. <view class="confirm-btn" @click="saveEdit">确认添加</view>
  173. </view>
  174. </view>
  175. </uni-popup>
  176. <SharePopup :visible="showShare" :userId="userId" :share-title="shareTitle" :share-desc="shareDesc"
  177. :share-img="shareImg" view="makeDetail" @close="showShare = false" />
  178. </view>
  179. </template>
  180. <script>
  181. import tabbarView from "@/components/tabbar/tabbar.vue";
  182. import value from '../../uni_modules/uv-text/components/uv-text/value';
  183. import {
  184. mapMutations
  185. } from 'vuex'
  186. export default {
  187. components: {
  188. tabbarView,
  189. },
  190. data() {
  191. return {
  192. isLoading: false,
  193. selectedGender: null,
  194. tempGender: null,
  195. tabbars: [],
  196. ballColors: [
  197. "#FF6B6B", // 红色
  198. "#4ECDC4", // 青色
  199. "#45B7D1", // 蓝色
  200. "#96CEB4", // 绿色
  201. "#FFEEAD", // 黄色
  202. "#D4A5A5", // 粉色
  203. "#9A8194", // 紫色
  204. "#FF9F1C", // 橙色
  205. ],
  206. showError: false,
  207. formData: {
  208. nickname: "",
  209. sex: "其他",
  210. description: "",
  211. tags: [],
  212. },
  213. predefinedTags: [],
  214. showInfo: false,
  215. starImg: "",
  216. noteContent: "",
  217. starInfo: {},
  218. state: 2, //0 是用户输入星灵基因重组仓的状态 1 是用户已经完成了匹星灵展示页面 2是用户匹配中加载的状态 3是匹配到了待点击进入设置界面 (根据其它字段判断是否失败) 4是用户设置星灵信息的页面 5是用户查看星灵信息的页面 待入驻 6是用户已经已经入驻星球了
  219. sex: "",
  220. selectTags: [],
  221. info: {
  222. "id": 0,
  223. "sso_id": 0,
  224. "image_id": 0,
  225. "image": "",
  226. "nickname": "",
  227. "user_content": "",
  228. "content": "",
  229. "sex_id": 0,
  230. "tags": "",
  231. "status": 0
  232. },
  233. timeoutId: 0,
  234. showShare: false,
  235. shareTitle: "分享标题",
  236. shareDesc: "",
  237. shareImg: "",
  238. userId: 0,
  239. maxRetries: 10, // 最大重试次数
  240. retryCount: 0, // 当前重试次数
  241. pollingInterval: 30000, // 轮询间隔时间(毫秒)
  242. editContent: '',
  243. };
  244. },
  245. onLoad() {
  246. this.aIpipeiGetinfo("get");
  247. this.loadInfo()
  248. },
  249. methods: {
  250. ...mapMutations('switchingModule', ['setInformation', 'deleteInformation']),
  251. // 返回上一页
  252. goBack() {
  253. console.log(66);
  254. uni.navigateBack({
  255. delta: 1
  256. });
  257. },
  258. confirmGender() {
  259. // if (!this.noteContent) {
  260. // uni.showToast({
  261. // title: "请输入匹配条件",
  262. // icon: "none",
  263. // });
  264. // return;
  265. // }
  266. // this.selectedGender = this.noteContent;
  267. this.isLoading = true;
  268. this.closeContentPopUpWindow();
  269. this.state = 2
  270. this.apiPeiStar();
  271. },
  272. goToSetProfile() {
  273. this.state = 4;
  274. this.formData.nickname = ''
  275. this.formData.sex = ''
  276. this.formData.tags = ''
  277. },
  278. toggleTag(tag) {
  279. const index = this.formData.tags.indexOf(tag);
  280. if (index > -1) {
  281. this.formData.tags.splice(index, 1);
  282. } else {
  283. this.formData.tags.push(tag);
  284. }
  285. },
  286. handleJoin(type) {
  287. if (type === 1) {
  288. // 保存修改后的信息到服务器
  289. uni.request({
  290. url: this.$apiHost + "/AIpipei/gogogo",
  291. data: {
  292. uuid: getApp().globalData.uuid,
  293. nickname: this.starInfo.nickname,
  294. content: this.starInfo.content,
  295. },
  296. header: {
  297. "content-type": "application/x-www-form-urlencoded",
  298. sign: getApp().globalData.headerSign,
  299. },
  300. method: "POST",
  301. success: (res) => {
  302. console.log("res.data", res.data);
  303. uni.showToast({
  304. title: res.data.str,
  305. icon: "none",
  306. duration: 2000,
  307. });
  308. if (res.data.success === "yes") {
  309. this.aIpipeiGetinfo({
  310. polling: false
  311. });
  312. }
  313. }
  314. });
  315. } else {
  316. // 已入驻状态,直接跳转
  317. uni.navigateTo({
  318. url: '/pages/isLand/homeLand'
  319. });
  320. }
  321. },
  322. // 提交用户 开始创建的命令
  323. apiPeiStar() {
  324. uni.request({
  325. url: this.$apiHost + "/AIpipei/start",
  326. data: {
  327. uuid: getApp().globalData.uuid,
  328. content: this.noteContent,
  329. },
  330. header: {
  331. "content-type": "application/x-www-form-urlencoded",
  332. sign: getApp().globalData.headerSign,
  333. },
  334. // 设置60秒超时
  335. timeout: 60000,
  336. method: 'POST',
  337. success: (res) => {
  338. setTimeout(() => {
  339. if (res.data.str != "开始匹配") {
  340. uni.showToast({
  341. title: res.data.str,
  342. icon: "none",
  343. duration: 2000,
  344. });
  345. }
  346. if (res.data.success == "no") {
  347. setTimeout(() => {
  348. this.state = 0
  349. this.isLoading = false;
  350. this.aIpipeiGetinfo("get");
  351. this.loadInfo()
  352. }, 2000);
  353. // this.apiPeiStar();
  354. }
  355. if (res.data.str == "开始匹配") {
  356. this.aIpipeiGetinfo({
  357. polling: true
  358. })
  359. }
  360. }, 3000);
  361. },
  362. fail: (err) => {
  363. console.error("请求失败:", err);
  364. // 显示错误提示
  365. uni.showToast({
  366. title: "网络请求失败,请重试",
  367. icon: "none",
  368. duration: 2000,
  369. });
  370. // 重置加载状态
  371. },
  372. complete: () => {
  373. },
  374. });
  375. },
  376. loadInfo() {
  377. console.log({
  378. uuid: getApp().globalData.uuid,
  379. skey: getApp().globalData.skey,
  380. });
  381. uni.request({
  382. url: this.$apiHost + "/User/getinfo",
  383. data: {
  384. uuid: getApp().globalData.uuid,
  385. skey: getApp().globalData.skey,
  386. },
  387. header: {
  388. "content-type": "application/json",
  389. sign: getApp().globalData.headerSign,
  390. },
  391. success: (res) => {
  392. console.log("----:", JSON.parse(JSON.stringify(res.data)));
  393. if (res.data) {
  394. this.userId = res.data.user_id
  395. }
  396. },
  397. complete: (com) => {
  398. // uni.hideLoading();
  399. },
  400. fail: (e) => {
  401. console.log("----e:", e);
  402. },
  403. });
  404. },
  405. // 查询Ai匹配信息
  406. aIpipeiGetinfo({
  407. polling
  408. }) {
  409. // 清除之前的定时器
  410. if (this.timeoutId) {
  411. clearTimeout(this.timeoutId);
  412. this.timeoutId = 0;
  413. }
  414. // 检查是否超过最大重试次数
  415. if (polling && this.retryCount >= this.maxRetries) {
  416. uni.showToast({
  417. title: '匹配超时,请重新尝试',
  418. icon: 'none',
  419. duration: 2000
  420. });
  421. this.retryCount = 0;
  422. this.state = 0;
  423. return;
  424. }
  425. // 发起请求
  426. uni.request({
  427. url: this.$apiHost + "/AIpipei/getinfo",
  428. data: {
  429. uuid: getApp().globalData.uuid,
  430. },
  431. header: {
  432. "content-type": "application/json",
  433. sign: getApp().globalData.headerSign,
  434. },
  435. timeout: 60000,
  436. success: (res) => {
  437. console.log("查询到生成信息", res.data);
  438. // 重置重试计数
  439. this.retryCount = 0;
  440. if (res && res.data && res.data.info) {
  441. if (res.data.info.content) {
  442. res.data.info.content = res.data.info.content.replace(/^\n+/, '')
  443. console.log(res.data.info.content);
  444. }
  445. if (res.data.info && res.data.info.tags != "") {
  446. res.data.info.tags = res.data.info.tags.split(",");
  447. this.predefinedTags = res.data.info.tags.map(tag => {
  448. return {
  449. text: tag,
  450. value: tag
  451. }
  452. })
  453. console.log(666, res);
  454. this.setInformation(res.data.info)
  455. this.shareTitle = res.data.info.nickname
  456. this.shareDesc = res.data.info.content
  457. this.shareImg = res.data.info.image
  458. // this.userId = res.data.user_id
  459. } else {
  460. res.data.info.tags = []
  461. this.deleteInformation()
  462. }
  463. // 实现状态的判断
  464. // 更改状态为 用户还未匹配过 待输入匹配内容
  465. if (res.data.success == "no") {
  466. if (res.data.str == "没有匹配过" ) {
  467. this.state = 0
  468. setTimeout(() => {
  469. this.openContentPopUpWindow();
  470. }, 300);
  471. return ;
  472. }
  473. uni.showToast({
  474. title: res.data.str,
  475. icon: "none",
  476. duration: 2000,
  477. });
  478. setTimeout(() => {
  479. this.state = 0
  480. setTimeout(() => {
  481. this.openContentPopUpWindow();
  482. }, 300);
  483. }, 2000);
  484. }
  485. // 更改状态为 用户还匹配成功时 待点击设置心灵简介
  486. if (res.data.info.image && res.data.info.status == 2) {
  487. this.state = 1
  488. this.isLoading = false
  489. // this.openContentPopUpWindow();
  490. }
  491. if (res.data.info.image && res.data.info.status == 1) {
  492. this.state = 6
  493. this.isLoading = false
  494. }
  495. if (res.data.info.image && res.data.info.status == 3) {
  496. this.state = 5
  497. this.isLoading = false
  498. }
  499. this.starInfo = res.data.info;
  500. if (res.data.info.content) {
  501. this.formData.description = res.data.info.content;
  502. }
  503. }
  504. },
  505. fail: (err) => {
  506. console.error("请求失败:", err);
  507. // 增加重试计数
  508. this.retryCount++;
  509. // 显示错误提示
  510. uni.showToast({
  511. title: `网络请求失败,第${this.retryCount}次重试`,
  512. icon: "none",
  513. duration: 2000,
  514. });
  515. // 如果是网络超时,自动重试
  516. if (err.errMsg.includes("timeout")) {
  517. setTimeout(() => {
  518. console.log("请求超时,正在重试...");
  519. this.aIpipeiGetinfo({
  520. polling: true
  521. });
  522. }, 6000);
  523. }
  524. },
  525. complete: () => {
  526. // 如果需要继续轮询,设置下一次请求
  527. if (polling) {
  528. this.timeoutId = setTimeout(() => {
  529. this.aIpipeiGetinfo({
  530. polling: true
  531. });
  532. }, this.pollingInterval);
  533. }
  534. }
  535. });
  536. },
  537. // 保存表单信息
  538. submitStar() {
  539. this.formData.tags = this.selectTags.join(",");
  540. let that = this;
  541. uni.showLoading({
  542. mask: true,
  543. });
  544. if (this.formData.sex) {
  545. this.formData.sex = this.genderScreeningId(this.formData.sex);
  546. }
  547. console.log({
  548. uuid: getApp().globalData.uuid,
  549. sex: this.formData.sex,
  550. name: this.formData.nickname,
  551. content: this.formData.description,
  552. tags: this.formData.tags,
  553. }, 2000);
  554. uni.request({
  555. url: this.$apiHost + "/AIpipei/save",
  556. data: {
  557. uuid: getApp().globalData.uuid,
  558. sex: this.formData.sex,
  559. nickname: this.formData.nickname,
  560. content: this.formData.description,
  561. tags: this.formData.tags,
  562. },
  563. header: {
  564. "content-type": "application/x-www-form-urlencoded",
  565. sign: getApp().globalData.headerSign,
  566. },
  567. method: 'POST',
  568. // 设置60秒超时
  569. timeout: 10000,
  570. success: (res) => {
  571. console.log("res.data", res.data);
  572. uni.showToast({
  573. title: res.data.str,
  574. icon: "none",
  575. duration: 2000,
  576. });
  577. if (res.data.success === "yes") {
  578. setTimeout(() => {
  579. that.aIpipeiGetinfo({
  580. polling: false
  581. });
  582. }, 300);
  583. }
  584. },
  585. fail: (err) => {
  586. console.error("请求失败:", err);
  587. // 显示错误提示
  588. uni.showToast({
  589. title: "网络请求失败,请重试",
  590. icon: "none",
  591. duration: 2000,
  592. });
  593. },
  594. complete: () => {
  595. uni.hideLoading();
  596. },
  597. });
  598. },
  599. selectGender(option) {
  600. this.formData.sex = option;
  601. this.sex = option;
  602. },
  603. openContentPopUpWindow() {
  604. if (this.$refs.openContentPopUpWindow) {
  605. console.log(9999, "打开");
  606. this.$refs.openContentPopUpWindow.open();
  607. }
  608. },
  609. closeContentPopUpWindow() {
  610. if (this.$refs.openContentPopUpWindow) {
  611. this.$refs.openContentPopUpWindow.close();
  612. }
  613. },
  614. genderScreening(str) {
  615. switch (str) {
  616. case '0':
  617. return '男'
  618. case '1':
  619. return '女'
  620. case '2':
  621. return '其它'
  622. }
  623. },
  624. genderScreeningId(str) {
  625. switch (str) {
  626. case 'male':
  627. return 0
  628. case 'female':
  629. return 1
  630. case 'other':
  631. return 2
  632. }
  633. },
  634. // 显示编辑弹窗
  635. showEditPopup() {
  636. this.editContent = this.starInfo.content;
  637. this.$refs.editPopup.open();
  638. },
  639. // 关闭编辑弹窗
  640. closeEditPopup() {
  641. this.$refs.editPopup.close();
  642. },
  643. // 保存编辑内容
  644. saveEdit() {
  645. this.starInfo.content = this.editContent;
  646. this.closeEditPopup();
  647. },
  648. },
  649. };
  650. </script>
  651. <style lang="scss">
  652. @import "./myStar.scss";
  653. .openContentPopUpWindow {
  654. ::v-deep.uv-textarea {
  655. width: 694rpx !important;
  656. border-radius: 20rpx !important;
  657. border: 1rpx solid #000000 !important;
  658. margin: 0 auto;
  659. margin-bottom: 44rpx;
  660. min-height: 300rpx;
  661. padding-bottom: 40rpx;
  662. .uv-textarea__field {
  663. min-height: 200rpx !important;
  664. font-weight: 400;
  665. font-size: 28rpx;
  666. color: #1f1f1f;
  667. }
  668. }
  669. }
  670. .textarea-container {
  671. .textarea {
  672. background: #f2f6f2 !important;
  673. min-height: 100rpx;
  674. }
  675. }
  676. .tags-container {
  677. ::v-deep.checklist-box {
  678. border-radius: 16rpx !important;
  679. border: 2rpx solid #1f1f1f !important;
  680. background-color: #fff !important;
  681. display: flex;
  682. align-items: center;
  683. justify-content: center;
  684. .checklist-text {
  685. font-size: 28rpx;
  686. color: #1f1f1f;
  687. font-family: "PingFang SC-Bold" !important;
  688. }
  689. &.is-checked {
  690. background: #f7ffea !important;
  691. border-color: #7ebc00 !important;
  692. .checklist-text {
  693. color: #1f1f1f !important;
  694. }
  695. }
  696. }
  697. }
  698. .star-container {
  699. /* 自定义导航栏样式 */
  700. .custom-navbar {
  701. display: flex;
  702. flex-direction: row;
  703. align-items: center;
  704. justify-content: space-between;
  705. width: 100%;
  706. height: calc(90rpx + var(--status-bar-height));
  707. padding: 0 20rpx;
  708. padding-top: var(--status-bar-height);
  709. background-color: transparent;
  710. position: fixed;
  711. top: 0;
  712. left: 0;
  713. z-index: 100;
  714. background: transparent;
  715. &::before {
  716. content: '';
  717. position: absolute;
  718. top: 0;
  719. left: 0;
  720. width: 100%;
  721. height: var(--status-bar-height);
  722. background-color: #fff;
  723. z-index: -1;
  724. }
  725. .navbar-left {
  726. width: 80rpx;
  727. height: 80rpx;
  728. display: flex;
  729. align-items: center;
  730. justify-content: center;
  731. .fa-angle-left {
  732. font-size: 48rpx;
  733. color: #333;
  734. }
  735. }
  736. .navbar-right {
  737. width: 80rpx;
  738. height: 80rpx;
  739. display: flex;
  740. justify-content: center;
  741. align-items: center;
  742. .fa-ellipsis-h {
  743. font-size: 36rpx;
  744. color: #333;
  745. }
  746. }
  747. }
  748. }
  749. .edit-popup {
  750. width: 600rpx;
  751. background: #fff;
  752. border-radius: 24rpx;
  753. padding: 40rpx 32rpx;
  754. .popup-title {
  755. font-size: 32rpx;
  756. font-weight: bold;
  757. text-align: center;
  758. margin-bottom: 32rpx;
  759. color: #000;
  760. }
  761. .popup-content {
  762. margin-bottom: 32rpx;
  763. .edit-textarea {
  764. background: #F7F7F7;
  765. border-radius: 16rpx;
  766. padding: 24rpx;
  767. min-height: 160rpx;
  768. ::v-deep .uv-textarea__field {
  769. font-size: 28rpx;
  770. color: #333;
  771. }
  772. }
  773. }
  774. .popup-buttons {
  775. display: flex;
  776. justify-content: space-between;
  777. gap: 24rpx;
  778. .cancel-btn,
  779. .confirm-btn {
  780. flex: 1;
  781. height: 88rpx;
  782. line-height: 88rpx;
  783. text-align: center;
  784. border-radius: 44rpx;
  785. font-size: 32rpx;
  786. font-weight: 500;
  787. }
  788. .cancel-btn {
  789. background: #fff;
  790. color: #333;
  791. border: 2rpx solid #E5E5E5;
  792. }
  793. .confirm-btn {
  794. background: #000;
  795. color: #fff;
  796. }
  797. }
  798. }
  799. .description-title {
  800. display: flex;
  801. justify-content: space-between;
  802. align-items: center;
  803. .edit-button {
  804. color: #7ebc00;
  805. font-size: 28rpx;
  806. display: flex;
  807. align-items: center;
  808. .fa-angle-right {
  809. margin-left: 10rpx;
  810. }
  811. }
  812. }
  813. </style>