123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866 |
- <template>
- <view class="star-container">
- <PageHeader title="" class="PageHeader" v-if="state == 1">
- <template v-slot:center> </template>
- </PageHeader>
- <!-- 星灵基因重组仓弹窗 -->
- <view class="gender-popup" v-if="state == 0">
- <NicknamePopup :closeOnClickOverlay="false" title="星灵基因重组仓" subtitle="" class="openContentPopUpWindow"
- ref="openContentPopUpWindow" @close="goBack()">
- <template v-slot:content>
- <uv-textarea v-model="noteContent" maxlength="200" count autoHeight
- placeholder="可描述你想要重新赋予Ta的形象、性别、性格、身份、兴趣爱好等(不会展示给其他人,仅你自己知道),示例:有一头波浪状的橙色头发,喜欢运动的阳光男孩..."></uv-textarea>
- <view class="btn-box blick-btn-animation" @tap="confirmGender">创建星灵</view>
- </template>
- </NicknamePopup>
- </view>
- <!-- 加载动画区域 -->
- <view class="loading-area" v-if="state == 2 || isLoading">
- <image src="../../static/me/loadAnimation.gif" mode="widthFix"></image>
- </view>
- <!-- 角色展示页面 -->
- <view class="character-page" v-else-if="state == 1">
- <view class="character-container">
- <image :src="starInfo.image || ''" mode="widthFix" class="character-image">
- </image>
- </view>
- <view class="bottom-button" @tap="goToSetProfile"> 设置星灵简介 </view>
- </view>
- <!-- 表单页面 -->
- <view class="form-page" v-else-if="state == 4">
- <PageHeader title="设置星灵简介" class="PageHeader">
- <template v-slot:center> </template>
- </PageHeader>
- <view class="reserveASeat"></view>
- <form @submit="submitForm">
- <view class="form-group">
- <view class="label">
- <text class="required">*</text>
- <text>昵称</text>
- </view>
- <input class="input" v-model="formData.nickname" placeholder="给星灵取个名字"
- :class="{ error: showError && !formData.nickname }" />
- </view>
- <view class="form-group">
- <view class="label">性别</view>
- <view class="gender-options">
- <view class="gender-option" :class="sex == 'male' ? 'selected' : ''"
- @tap="selectGender('male')">
- <view class="gender-icon male">
- <image src="../../static/me/wd_icon_nan.png" mode="aspectFit"></image>
- 男性
- </view>
- </view>
- <view class="gender-option" :class="sex == 'female' ? 'selected' : ''"
- @tap="selectGender('female')">
- <view class="gender-icon female">
- <image src="../../static/me/wd_icon_nv.png" mode="aspectFit"></image>
- 女性
- </view>
- </view>
- <view class="gender-option" :class="sex == 'other' ? 'selected' : ''"
- @tap="selectGender('other')">
- <view class="gender-icon other">
- <image src="../../static/me/wd_icon_qita.png" mode="aspectFit"></image>
- 其它
- </view>
- </view>
- </view>
- </view>
- <view class="form-group">
- <view class="label">
- <text class="required">*</text>
- <text>人物简介</text>
- </view>
- <view class="textarea-container">
- <textarea class="textarea" v-model="formData.description"
- placeholder="填写这个角色的人物介绍,例如性格、身份、背景与历程..." :maxlength="500"
- :class="{ error: showError && !formData.description }" autoHeight />
- <text class="word-count">{{ formData.description.length }}/500</text>
- </view>
- </view>
- <view class="form-group">
- <view class="label">人物标签</view>
- <!-- <scroll-view class="tags-scroll" scroll-x="true" show-scrollbar="false">
- <view class="tags-container">
- <view class="tag" v-for="tag in predefinedTags" :key="tag">
- {{ tag }}
- </view>
- </view>
- </scroll-view> -->
- <view class="tags-container">
- <!-- <view class="tag" :class="{ active: tagSet.has(tag) }" v-for="tag in predefinedTags" :key="tag"
- @tap="switchTag(tag)">
- {{ tag }}
- </view> -->
- <uni-data-checkbox mode="tag" multiple v-model="selectTags"
- :localdata="predefinedTags"></uni-data-checkbox>
- </view>
- </view>
- </form>
- <view class="submit-button" @tap="submitStar"> 确定并提交 </view>
- </view>
- <!-- 角色信息展示页面 -->
- <view class="character-info" v-else-if="state == 5 || state == 6">
- <view class="custom-navbar">
- <view class="navbar-left" @click="goBack">
- <text class="fa fa-angle-left" style="color: #000;"></text>
- </view>
- <view class="navbar-right" @click="showShare = true">
- <text class="fa fa-ellipsis-h"></text>
- </view>
- </view>
- <view class="info-container">
- <!-- 角色立绘区域 -->
- <view class="character-portrait">
- <image :src="starInfo.image" mode="widthFix" class="portrait-image"></image>
- </view>
- <!-- 角色信息板块 -->
- <view class="info-section">
- <view class="character-name">
- <uv-input v-if="state == 5" v-model="starInfo.nickname" placeholder="请输入昵称" border="none" />
- <text v-else>{{ starInfo.nickname }}</text>
- <image class="male" v-if="starInfo.sex_id == 1" src="../../static/me/wd_icon_nan.png"
- mode="aspectFit">
- </image>
- <image class="female" v-else-if="starInfo.sex_id == 2" src="../../static/me/wd_icon_nv.png"
- mode="aspectFit">
- </image>
- <image class="other" v-else-if="starInfo.sex_id == 3" src="../../static/me/wd_icon_qita.png"
- mode="aspectFit"></image>
- </view>
- <!-- 人物简介 -->
- <view class="description-box">
- <view class="description-title">
- <view>Ta的设定</view>
- <view v-if="state == 5" class="edit-button" @click="showEditPopup">
- 编辑<text class="fa fa-angle-right" style="color: #000;"></text>
- </view>
- </view>
- <view class="description-text">
- <text>{{ starInfo.content }}</text>
- </view>
- </view>
- <!-- 标签展示 -->
- <view class="description-box">
- <view class="description-title">
- <view>人物标签</view>
- </view>
- <view class="tags-box">
- <view class="tag-item" v-for="tag in starInfo.tags" :key="tag">
- {{ tag }}
- </view>
- </view>
- </view>
- </view>
- </view>
- <!-- 底部按钮 -->
- <view class="join-button blick-btn-animation" @tap="handleJoin(1)" v-if="state == 5"> 入驻星球 </view>
- <view class="join-button blick-btn-animation" @tap="handleJoin(0)" v-if="state == 6"> 已入驻星球(点击进入星球) </view>
- </view>
- <!-- 编辑弹窗 -->
- <uni-popup ref="editPopup" type="center">
- <view class="edit-popup">
- <view class="popup-title">修改设定</view>
- <view class="popup-content">
- <uv-textarea v-model="editContent" :maxlength="500" count autoHeight placeholder="输入Ta的设定"
- class="edit-textarea" />
- </view>
- <view class="popup-buttons">
- <view class="cancel-btn" @click="closeEditPopup">再考虑一下</view>
- <view class="confirm-btn" @click="saveEdit">确认添加</view>
- </view>
- </view>
- </uni-popup>
- <SharePopup :visible="showShare" :userId="userId" :share-title="shareTitle" :share-desc="shareDesc"
- :share-img="shareImg" view="makeDetail" @close="showShare = false" />
- </view>
- </template>
- <script>
- import tabbarView from "@/components/tabbar/tabbar.vue";
- import value from '../../uni_modules/uv-text/components/uv-text/value';
- import {
- mapMutations
- } from 'vuex'
- export default {
- components: {
- tabbarView,
- },
- data() {
- return {
- isLoading: false,
- selectedGender: null,
- tempGender: null,
- tabbars: [],
- ballColors: [
- "#FF6B6B", // 红色
- "#4ECDC4", // 青色
- "#45B7D1", // 蓝色
- "#96CEB4", // 绿色
- "#FFEEAD", // 黄色
- "#D4A5A5", // 粉色
- "#9A8194", // 紫色
- "#FF9F1C", // 橙色
- ],
- showError: false,
- formData: {
- nickname: "",
- sex: "其他",
- description: "",
- tags: [],
- },
- predefinedTags: [],
- showInfo: false,
- starImg: "",
- noteContent: "",
- starInfo: {},
- state: 2, //0 是用户输入星灵基因重组仓的状态 1 是用户已经完成了匹星灵展示页面 2是用户匹配中加载的状态 3是匹配到了待点击进入设置界面 (根据其它字段判断是否失败) 4是用户设置星灵信息的页面 5是用户查看星灵信息的页面 待入驻 6是用户已经已经入驻星球了
- sex: "",
- selectTags: [],
- info: {
- "id": 0,
- "sso_id": 0,
- "image_id": 0,
- "image": "",
- "nickname": "",
- "user_content": "",
- "content": "",
- "sex_id": 0,
- "tags": "",
- "status": 0
- },
- timeoutId: 0,
- showShare: false,
- shareTitle: "分享标题",
- shareDesc: "",
- shareImg: "",
- userId: 0,
- maxRetries: 10, // 最大重试次数
- retryCount: 0, // 当前重试次数
- pollingInterval: 30000, // 轮询间隔时间(毫秒)
- editContent: '',
- };
- },
- onLoad() {
- this.aIpipeiGetinfo("get");
- this.loadInfo()
- },
- methods: {
- ...mapMutations('switchingModule', ['setInformation', 'deleteInformation']),
- // 返回上一页
- goBack() {
- console.log(66);
- uni.navigateBack({
- delta: 1
- });
- },
- confirmGender() {
- // this.selectedGender = this.noteContent;
- this.isLoading = true;
- this.closeContentPopUpWindow();
- this.state = 2
- this.apiPeiStar();
- },
- goToSetProfile() {
- this.state = 4;
- this.formData.nickname = ''
- this.formData.sex = ''
- this.formData.tags = ''
- },
- toggleTag(tag) {
- const index = this.formData.tags.indexOf(tag);
- if (index > -1) {
- this.formData.tags.splice(index, 1);
- } else {
- this.formData.tags.push(tag);
- }
- },
- handleJoin(type) {
- if (type === 1) {
- // 保存修改后的信息到服务器
- uni.request({
- url: this.$apiHost + "/AIpipei/gogogo",
- data: {
- uuid: getApp().globalData.uuid,
- nickname: this.starInfo.nickname,
- content: this.starInfo.content,
- },
- header: {
- "content-type": "application/x-www-form-urlencoded",
- sign: getApp().globalData.headerSign,
- },
- method: "POST",
- success: (res) => {
- this.aIpipeiGetinfo({
- polling: false
- });
- }
- });
- } else {
- // 已入驻状态,直接跳转
- uni.navigateTo({
- url: '/pages/isLand/homeLand'
- });
- }
- },
- // 提交用户 开始创建的命令
- apiPeiStar() {
- if (!this.noteContent) {
- uni.showToast({
- title: "请输入匹配条件",
- icon: "none",
- });
- return;
- }
- uni.request({
- url: this.$apiHost + "/AIpipei/start",
- data: {
- uuid: getApp().globalData.uuid,
- content: this.noteContent,
- },
- header: {
- "content-type": "application/x-www-form-urlencoded",
- sign: getApp().globalData.headerSign,
- },
- // 设置60秒超时
- timeout: 60000,
- method: 'POST',
- success: (res) => {
- setTimeout(() => {
- if (res.data.str != "开始匹配") {
- uni.showToast({
- title: res.data.str,
- icon: "none",
- duration: 2000,
- });
- }
- if (res.data.str == "内容不能为空") {
- this.openContentPopUpWindow();
- this.state = 0
- this.apiPeiStar();
- }
- if (res.data.str == "开始匹配") {
- this.aIpipeiGetinfo({
- polling: true
- })
- }
- }, 3000);
- },
- fail: (err) => {
- console.error("请求失败:", err);
- // 显示错误提示
- uni.showToast({
- title: "网络请求失败,请重试",
- icon: "none",
- duration: 2000,
- });
- // 重置加载状态
- },
- complete: () => {
- },
- });
- },
- loadInfo() {
- console.log({
- uuid: getApp().globalData.uuid,
- skey: getApp().globalData.skey,
- });
- uni.request({
- url: this.$apiHost + "/User/getinfo",
- data: {
- uuid: getApp().globalData.uuid,
- skey: getApp().globalData.skey,
- },
- header: {
- "content-type": "application/json",
- sign: getApp().globalData.headerSign,
- },
- success: (res) => {
- console.log("----:", JSON.parse(JSON.stringify(res.data)));
- if (res.data) {
- this.userId = res.data.user_id
- }
- },
- complete: (com) => {
- // uni.hideLoading();
- },
- fail: (e) => {
- console.log("----e:", e);
- },
- });
- },
- // 查询Ai匹配信息
- aIpipeiGetinfo({
- polling
- }) {
- // 清除之前的定时器
- if (this.timeoutId) {
- clearTimeout(this.timeoutId);
- this.timeoutId = 0;
- }
- // 检查是否超过最大重试次数
- if (polling && this.retryCount >= this.maxRetries) {
- uni.showToast({
- title: '匹配超时,请重新尝试',
- icon: 'none',
- duration: 2000
- });
- this.retryCount = 0;
- this.state = 0;
- return;
- }
- // 发起请求
- uni.request({
- url: this.$apiHost + "/AIpipei/getinfo",
- data: {
- uuid: getApp().globalData.uuid,
- },
- header: {
- "content-type": "application/json",
- sign: getApp().globalData.headerSign,
- },
- timeout: 60000,
- success: (res) => {
- console.log("查询到生成信息", res.data);
- // 重置重试计数
- this.retryCount = 0;
- if (res && res.data && res.data.info) {
- if (res.data.info.content) {
- res.data.info.content = res.data.info.content.replace(/^\n+/, '')
- console.log(res.data.info.content);
- }
- if (res.data.info && res.data.info.tags != "") {
- res.data.info.tags = res.data.info.tags.split(",");
- this.predefinedTags = res.data.info.tags.map(tag => {
- return {
- text: tag,
- value: tag
- }
- })
- console.log(666, res);
- this.setInformation(res.data.info)
- this.shareTitle = res.data.info.nickname
- this.shareDesc = res.data.info.content
- this.shareImg = res.data.info.image
- // this.userId = res.data.user_id
- } else {
- res.data.info.tags = []
- this.deleteInformation()
- }
- // 实现状态的判断
- // 更改状态为 用户还未匹配过 待输入匹配内容
- if (res.data.str == "没有匹配过" && res.data.info) {
- this.state = 0
- setTimeout(() => {
- this.openContentPopUpWindow();
- }, 300);
- }
- // 更改状态为 用户还匹配成功时 待点击设置心灵简介
- if (res.data.info.image && res.data.info.status == 2) {
- this.state = 1
- this.isLoading = false
- // this.openContentPopUpWindow();
- }
- if (res.data.info.image && res.data.info.status == 1) {
- this.state = 6
- this.isLoading = false
- }
- if (res.data.info.image && res.data.info.status == 3) {
- this.state = 5
- this.isLoading = false
- }
- this.starInfo = res.data.info;
- if (res.data.info.content) {
- this.formData.description = res.data.info.content;
- }
- }
- },
- fail: (err) => {
- console.error("请求失败:", err);
- // 增加重试计数
- this.retryCount++;
- // 显示错误提示
- uni.showToast({
- title: `网络请求失败,第${this.retryCount}次重试`,
- icon: "none",
- duration: 2000,
- });
- // 如果是网络超时,自动重试
- if (err.errMsg.includes("timeout")) {
- setTimeout(() => {
- console.log("请求超时,正在重试...");
- this.aIpipeiGetinfo({
- polling: true
- });
- }, 6000);
- }
- },
- complete: () => {
- // 如果需要继续轮询,设置下一次请求
- if (polling) {
- this.timeoutId = setTimeout(() => {
- this.aIpipeiGetinfo({
- polling: true
- });
- }, this.pollingInterval);
- }
- }
- });
- },
- // 保存表单信息
- submitStar() {
- this.formData.tags = this.selectTags.join(",");
- let that = this;
- uni.showLoading({
- mask: true,
- });
- if (this.formData.sex) {
- this.formData.sex = this.genderScreeningId(this.formData.sex);
- }
- console.log({
- uuid: getApp().globalData.uuid,
- sex: this.formData.sex,
- name: this.formData.nickname,
- content: this.formData.description,
- tags: this.formData.tags,
- }, 2000);
- uni.request({
- url: this.$apiHost + "/AIpipei/save",
- data: {
- uuid: getApp().globalData.uuid,
- sex: this.formData.sex,
- nickname: this.formData.nickname,
- content: this.formData.description,
- tags: this.formData.tags,
- },
- header: {
- "content-type": "application/x-www-form-urlencoded",
- sign: getApp().globalData.headerSign,
- },
- method: 'POST',
- // 设置60秒超时
- timeout: 10000,
- success: (res) => {
- console.log("res.data", res.data);
- uni.showToast({
- title: res.data.str,
- icon: "none",
- duration: 2000,
- });
- if (res.data.success === "yes") {
- setTimeout(() => {
- that.aIpipeiGetinfo({
- polling: false
- });
- }, 300);
- }
- },
- fail: (err) => {
- console.error("请求失败:", err);
- // 显示错误提示
- uni.showToast({
- title: "网络请求失败,请重试",
- icon: "none",
- duration: 2000,
- });
- },
- complete: () => {
- uni.hideLoading();
- },
- });
- },
- selectGender(option) {
- this.formData.sex = option;
- this.sex = option;
- },
- openContentPopUpWindow() {
- if (this.$refs.openContentPopUpWindow) {
- console.log(9999, "打开");
- this.$refs.openContentPopUpWindow.open();
- }
- },
- closeContentPopUpWindow() {
- if (this.$refs.openContentPopUpWindow) {
- this.$refs.openContentPopUpWindow.close();
- }
- },
- genderScreening(str) {
- switch (str) {
- case '0':
- return '男'
- case '1':
- return '女'
- case '2':
- return '其它'
- }
- },
- genderScreeningId(str) {
- switch (str) {
- case 'male':
- return 0
- case 'female':
- return 1
- case 'other':
- return 2
- }
- },
- // 显示编辑弹窗
- showEditPopup() {
- this.editContent = this.starInfo.content;
- this.$refs.editPopup.open();
- },
- // 关闭编辑弹窗
- closeEditPopup() {
- this.$refs.editPopup.close();
- },
- // 保存编辑内容
- saveEdit() {
- this.starInfo.content = this.editContent;
- this.closeEditPopup();
- },
- },
- };
- </script>
- <style lang="scss">
- @import "./myStar.scss";
- .openContentPopUpWindow {
- ::v-deep.uv-textarea {
- width: 694rpx !important;
- border-radius: 20rpx !important;
- border: 1rpx solid #000000 !important;
- margin: 0 auto;
- margin-bottom: 44rpx;
- min-height: 300rpx;
- padding-bottom: 40rpx;
- .uv-textarea__field {
- min-height: 200rpx !important;
- font-weight: 400;
- font-size: 28rpx;
- color: #1f1f1f;
- }
- }
- }
- .textarea-container {
- .textarea {
- background: #f2f6f2 !important;
- min-height: 100rpx;
- }
- }
- .tags-container {
- ::v-deep.checklist-box {
- border-radius: 16rpx !important;
- border: 2rpx solid #1f1f1f !important;
- background-color: #fff !important;
- display: flex;
- align-items: center;
- justify-content: center;
- .checklist-text {
- font-size: 28rpx;
- color: #1f1f1f;
- font-family: "PingFang SC-Bold" !important;
- }
- &.is-checked {
- background: #f7ffea !important;
- border-color: #7ebc00 !important;
- .checklist-text {
- color: #1f1f1f !important;
- }
- }
- }
- }
- .star-container {
- /* 自定义导航栏样式 */
- .custom-navbar {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- height: calc(90rpx + var(--status-bar-height));
- padding: 0 20rpx;
- padding-top: var(--status-bar-height);
- background-color: transparent;
- position: fixed;
- top: 0;
- left: 0;
- z-index: 100;
- background: transparent;
- &::before {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: var(--status-bar-height);
- background-color: #fff;
- z-index: -1;
- }
- .navbar-left {
- width: 80rpx;
- height: 80rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- .fa-angle-left {
- font-size: 48rpx;
- color: #333;
- }
- }
- .navbar-right {
- width: 80rpx;
- height: 80rpx;
- display: flex;
- justify-content: center;
- align-items: center;
- .fa-ellipsis-h {
- font-size: 36rpx;
- color: #333;
- }
- }
- }
- }
- .edit-popup {
- width: 600rpx;
- background: #fff;
- border-radius: 24rpx;
- padding: 40rpx 32rpx;
- .popup-title {
- font-size: 32rpx;
- font-weight: bold;
- text-align: center;
- margin-bottom: 32rpx;
- color: #000;
- }
- .popup-content {
- margin-bottom: 32rpx;
- .edit-textarea {
- background: #F7F7F7;
- border-radius: 16rpx;
- padding: 24rpx;
- min-height: 160rpx;
- ::v-deep .uv-textarea__field {
- font-size: 28rpx;
- color: #333;
- }
- }
- }
- .popup-buttons {
- display: flex;
- justify-content: space-between;
- gap: 24rpx;
- .cancel-btn,
- .confirm-btn {
- flex: 1;
- height: 88rpx;
- line-height: 88rpx;
- text-align: center;
- border-radius: 44rpx;
- font-size: 32rpx;
- font-weight: 500;
- }
- .cancel-btn {
- background: #fff;
- color: #333;
- border: 2rpx solid #E5E5E5;
- }
- .confirm-btn {
- background: #000;
- color: #fff;
- }
- }
- }
- .description-title {
- display: flex;
- justify-content: space-between;
- align-items: center;
- .edit-button {
- color: #7ebc00;
- font-size: 28rpx;
- display: flex;
- align-items: center;
- .fa-angle-right {
- margin-left: 10rpx;
- }
- }
- }
- </style>
|