| @@ -0,0 +1,91 @@ | |||
| <template> | |||
| <div> | |||
| <van-swipe-cell v-for="(item, index) in videoList"> | |||
| <div class="itemList"> | |||
| <div | |||
| v-if="videoList.length > 0" | |||
| class="videoModel" | |||
| :key="index" | |||
| @click="$parent.goDetail(item)" | |||
| > | |||
| <!-- 左侧图片 --> | |||
| <div class="videoPrv"> | |||
| <img src="@/assets/img/BG@2x.png" /> | |||
| <div v-if="item.videoStatus == 0" class="cover">草稿</div> | |||
| <div v-if="item.videoStatus == 1" class="cover">视频生成中</div> | |||
| <div v-if="item.videoStatus == 3" class="cover">视频生成失败</div> | |||
| <!-- <div v-if="item.videoStatus == ?" class="cover">排队中</div> --> | |||
| </div> | |||
| <!-- 中间文字 --> | |||
| <div class="videoInfo"> | |||
| <div class="videoName"> | |||
| {{ item.title || "暂无" }} | |||
| </div> | |||
| <div class="createTime"> | |||
| 视频时长:{{ $parent.formatSeconds(item.videoTime) }} | |||
| </div> | |||
| <div class="createTime"> | |||
| 视频容量:{{ $parent.bytesToSize(item.videoSize) }} | |||
| </div> | |||
| <div class="createTime"> | |||
| 创建时间:{{ | |||
| $parent.changeTime(item.createDate, "YYYY-MM-DD hh:mm:ss") | |||
| }} | |||
| </div> | |||
| </div> | |||
| <!-- 右侧更多 --> | |||
| <div class="showMore" @click.stop="showDialog=!showDialog"> | |||
| <div></div> | |||
| <div></div> | |||
| <div></div> | |||
| </div> | |||
| <van-dialog v-model="showDialog" title="标题" show-cancel-button> | |||
| 123123123123 | |||
| </van-dialog> | |||
| </div> | |||
| <div v-if="videoList.length <= 0" class="noWork"> | |||
| 您还没有视频作品 | |||
| </div> | |||
| </div> | |||
| <template #right> | |||
| <van-button | |||
| square | |||
| text="删除" | |||
| type="danger" | |||
| class="delete-button" | |||
| @click="$parent.goDelete(item.id)" | |||
| /> | |||
| </template> | |||
| </van-swipe-cell> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| name: 'SrcMyVideoItem', | |||
| props: { | |||
| videoList: { | |||
| type: Array, | |||
| required: true | |||
| } | |||
| }, | |||
| data() { | |||
| return { | |||
| showDialog:false | |||
| }; | |||
| }, | |||
| mounted() { | |||
| }, | |||
| methods: { | |||
| }, | |||
| }; | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| </style> | |||
| @@ -1,5 +1,5 @@ | |||
| <template> | |||
| <div class="tailBox"> | |||
| <div v-if="false" class="tailBox"> | |||
| <!-- <div class="title">联系我们</div> --> | |||
| <!-- <div class="taillong"> | |||
| <img src="../../assets/img/LOGO1.png" alt> | |||
| @@ -10,6 +10,8 @@ import 'lib-flexible' | |||
| import axios from "axios" | |||
| import ElementUI from 'element-ui'; //引入js | |||
| import 'element-ui/lib/theme-chalk/index.css';//引入css | |||
| import "@/styles/reset.scss"; // 引入清除默认样式 | |||
| import "@/styles/index.scss"; // 引入全局样式 | |||
| Vue.use(ElementUI); | |||
| Vue.use(Vant) | |||
| @@ -44,6 +44,19 @@ const routes = [ | |||
| name: 'chooseModel', | |||
| component: () => import("../views/model/chooseModel"), | |||
| }, | |||
| // 模板预览 | |||
| { | |||
| path: '/previewModel', | |||
| name: 'previewModel', | |||
| component: () => import("../views/model/previewModel"), | |||
| }, | |||
| // 编辑模板 | |||
| { | |||
| path: '/editModel', | |||
| name: 'editModel', | |||
| component: () => import("../views/model/editModel"), | |||
| }, | |||
| // 录入文案 | |||
| { | |||
| path: '/getPaper', | |||
| @@ -0,0 +1,13 @@ | |||
| .floatRight { | |||
| float: right; | |||
| } | |||
| // 淡化文字 | |||
| .desalinate { | |||
| font-size: 12px; | |||
| font-weight: 400; | |||
| color: #666; | |||
| } | |||
| .redWord { | |||
| font-weight: normal; | |||
| color: red; | |||
| } | |||
| @@ -0,0 +1,284 @@ | |||
| /*! | |||
| * ress.css • v4.0.0 | |||
| * MIT License | |||
| * github.com/filipelinhares/ress | |||
| */ | |||
| /* # ================================================================= | |||
| # Global selectors | |||
| # ================================================================= */ | |||
| html { | |||
| box-sizing: border-box; | |||
| -webkit-text-size-adjust: 100%; /* Prevent adjustments of font size after orientation changes in iOS */ | |||
| word-break: normal; | |||
| -moz-tab-size: 4; | |||
| tab-size: 4; | |||
| } | |||
| *, | |||
| ::before, | |||
| ::after { | |||
| box-sizing: inherit; | |||
| background-repeat: no-repeat; /* Set `background-repeat: no-repeat` to all elements and pseudo elements */ | |||
| } | |||
| ::before, | |||
| ::after { | |||
| text-decoration: inherit; /* Inherit text-decoration and vertical align to ::before and ::after pseudo elements */ | |||
| vertical-align: inherit; | |||
| } | |||
| * { | |||
| padding: 0; /* Reset `padding` and `margin` of all elements */ | |||
| margin: 0; | |||
| } | |||
| /* # ================================================================= | |||
| # General elements | |||
| # ================================================================= */ | |||
| hr { | |||
| height: 0; /* Add the correct box sizing in Firefox */ | |||
| overflow: visible; /* Show the overflow in Edge and IE */ | |||
| color: inherit; /* Correct border color in Firefox. */ | |||
| } | |||
| details, | |||
| main { | |||
| display: block; /* Render the `main` element consistently in IE. */ | |||
| } | |||
| summary { | |||
| display: list-item; /* Add the correct display in all browsers */ | |||
| } | |||
| small { | |||
| font-size: 80%; /* Set font-size to 80% in `small` elements */ | |||
| } | |||
| [hidden] { | |||
| display: none; /* Add the correct display in IE */ | |||
| } | |||
| abbr[title] { | |||
| /* Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari */ | |||
| text-decoration: underline; | |||
| text-decoration: underline dotted; | |||
| border-bottom: none; /* Remove the bottom border in Chrome 57 */ | |||
| } | |||
| a { | |||
| background-color: transparent; /* Remove the gray background on active links in IE 10 */ | |||
| } | |||
| a:active, | |||
| a:hover { | |||
| outline-width: 0; /* Remove the outline when hovering in all browsers */ | |||
| } | |||
| code, | |||
| kbd, | |||
| pre, | |||
| samp { | |||
| font-family: monospace, monospace; /* Specify the font family of code elements */ | |||
| } | |||
| pre { | |||
| font-size: 1em; /* Correct the odd `em` font sizing in all browsers */ | |||
| } | |||
| b, | |||
| strong { | |||
| font-weight: bolder; /* Add the correct font weight in Chrome, Edge, and Safari */ | |||
| } | |||
| /* https://gist.github.com/unruthless/413930 */ | |||
| sub, | |||
| sup { | |||
| position: relative; | |||
| font-size: 75%; | |||
| line-height: 0; | |||
| vertical-align: baseline; | |||
| } | |||
| sub { | |||
| bottom: -.25em; | |||
| } | |||
| sup { | |||
| top: -.5em; | |||
| } | |||
| table { | |||
| text-indent: 0; /* Remove text indentation in Chrome, Edge, and Safari */ | |||
| border-color: inherit; /* Correct border color in all Chrome, Edge, and Safari. */ | |||
| } | |||
| /* # ================================================================= | |||
| # Forms | |||
| # ================================================================= */ | |||
| input { | |||
| border-radius: 0; | |||
| } | |||
| /* Replace pointer cursor in disabled elements */ | |||
| [disabled] { | |||
| cursor: default; | |||
| } | |||
| [type='number']::-webkit-inner-spin-button, | |||
| [type='number']::-webkit-outer-spin-button { | |||
| height: auto; /* Correct the cursor style of increment and decrement buttons in Chrome */ | |||
| } | |||
| [type='search'] { | |||
| -webkit-appearance: textfield; /* Correct the odd appearance in Chrome and Safari */ | |||
| outline-offset: -2px; /* Correct the outline style in Safari */ | |||
| } | |||
| [type='search']::-webkit-search-decoration { | |||
| -webkit-appearance: none; /* Remove the inner padding in Chrome and Safari on macOS */ | |||
| } | |||
| textarea { | |||
| overflow: auto; /* Internet Explorer 11+ */ | |||
| resize: vertical; /* Specify textarea resizability */ | |||
| } | |||
| button, | |||
| input, | |||
| optgroup, | |||
| select, | |||
| textarea { | |||
| font: inherit; /* Specify font inheritance of form elements */ | |||
| } | |||
| optgroup { | |||
| font-weight: bold; /* Restore the font weight unset by the previous rule */ | |||
| } | |||
| button { | |||
| overflow: visible; /* Address `overflow` set to `hidden` in IE 8/9/10/11 */ | |||
| } | |||
| button, | |||
| select { | |||
| text-transform: none; /* Firefox 40+, Internet Explorer 11- */ | |||
| } | |||
| /* Apply cursor pointer to button elements */ | |||
| button, | |||
| [type='button'], | |||
| [type='reset'], | |||
| [type='submit'], | |||
| [role='button'] { | |||
| color: inherit; | |||
| cursor: pointer; | |||
| } | |||
| /* Remove inner padding and border in Firefox 4+ */ | |||
| button::-moz-focus-inner, | |||
| [type='button']::-moz-focus-inner, | |||
| [type='reset']::-moz-focus-inner, | |||
| [type='submit']::-moz-focus-inner { | |||
| padding: 0; | |||
| border-style: none; | |||
| } | |||
| /* Replace focus style removed in the border reset above */ | |||
| button:-moz-focusring, | |||
| [type='button']::-moz-focus-inner, | |||
| [type='reset']::-moz-focus-inner, | |||
| [type='submit']::-moz-focus-inner { | |||
| outline: 1px dotted ButtonText; | |||
| } | |||
| button, | |||
| html [type='button'], /* Prevent a WebKit bug where (2) destroys native `audio` and `video`controls in Android 4 */ | |||
| [type='reset'], | |||
| [type='submit'] { | |||
| -webkit-appearance: button; /* Correct the inability to style clickable types in iOS */ | |||
| } | |||
| /* Remove the default button styling in all browsers */ | |||
| button, | |||
| input, | |||
| select, | |||
| textarea { | |||
| background-color: transparent; | |||
| border-style: none; | |||
| } | |||
| a:focus, | |||
| button:focus, | |||
| input:focus, | |||
| select:focus, | |||
| textarea:focus { | |||
| outline-width: 0; | |||
| } | |||
| /* Style select like a standard input */ | |||
| select { | |||
| -moz-appearance: none; /* Firefox 36+ */ | |||
| -webkit-appearance: none; /* Chrome 41+ */ | |||
| } | |||
| select::-ms-expand { | |||
| display: none; /* Internet Explorer 11+ */ | |||
| } | |||
| select::-ms-value { | |||
| color: currentColor; /* Internet Explorer 11+ */ | |||
| } | |||
| legend { | |||
| display: table; /* Correct the text wrapping in Edge and IE */ | |||
| max-width: 100%; /* Correct the text wrapping in Edge and IE */ | |||
| max-width: 100%; /* Correct the text wrapping in Edge 18- and IE */ | |||
| color: inherit; /* Correct the color inheritance from `fieldset` elements in IE */ | |||
| white-space: normal; /* Correct the text wrapping in Edge and IE */ | |||
| border: 0; /* Correct `color` not being inherited in IE 8/9/10/11 */ | |||
| } | |||
| ::-webkit-file-upload-button { | |||
| font: inherit; /* Change font properties to `inherit` in Chrome and Safari */ | |||
| color: inherit; | |||
| /* Correct the inability to style clickable types in iOS and Safari */ | |||
| -webkit-appearance: button; | |||
| } | |||
| /* # ================================================================= | |||
| # Specify media element style | |||
| # ================================================================= */ | |||
| img { | |||
| border-style: none; /* Remove border when inside `a` element in IE 8/9/10 */ | |||
| } | |||
| /* Add the correct vertical alignment in Chrome, Firefox, and Opera */ | |||
| progress { | |||
| vertical-align: baseline; | |||
| } | |||
| /* # ================================================================= | |||
| # Accessibility | |||
| # ================================================================= */ | |||
| /* Specify the progress cursor of updating elements */ | |||
| [aria-busy='true'] { | |||
| cursor: progress; | |||
| } | |||
| /* Specify the pointer cursor of trigger elements */ | |||
| [aria-controls] { | |||
| cursor: pointer; | |||
| } | |||
| /* Specify the unstyled cursor of disabled, not-editable, or otherwise inoperable elements */ | |||
| [aria-disabled='true'] { | |||
| cursor: default; | |||
| } | |||
| @@ -0,0 +1,441 @@ | |||
| <template> | |||
| <div :class="inPage ? 'page active' : 'page'"> | |||
| <div id="top"></div> | |||
| <div class="logoBox" @click="go('/')"> | |||
| <img src="../../assets/img/logoh.png" alt class="logo" /> | |||
| <!-- <div class="logoTitle">metavatar</div> --> | |||
| </div> | |||
| <!-- 短信验证码登录 --> | |||
| <div class="loginBox" v-if="loginType == 1"> | |||
| <div class="welcome">登录邃芒</div> | |||
| <el-form ref="form" :rules="rules" :model="form"> | |||
| <el-form-item class="phone" prop="phone"> | |||
| <el-input class="phoneInput" v-model="form.phone"></el-input> | |||
| <div class="inputPhone">请输入您的手机号</div> | |||
| <el-button class="getCode" type="text" @click="getCode">{{ | |||
| codeInfo | |||
| }}</el-button> | |||
| </el-form-item> | |||
| <el-form-item class="code" prop="code"> | |||
| <el-input | |||
| class="codeInput" | |||
| v-model="form.code" | |||
| maxlength="10" | |||
| clearable | |||
| ></el-input> | |||
| <div class="inputCode">请输入短信验证码</div> | |||
| </el-form-item> | |||
| <el-form-item> | |||
| <el-button class="submitBtn" @click="loginByPhoneCode" | |||
| >登录/注册</el-button | |||
| > | |||
| </el-form-item> | |||
| </el-form> | |||
| </div> | |||
| <!-- 用户名密码登录 --> | |||
| <div class="loginBox" v-if="loginType == 2"> | |||
| <div class="welcome">登录邃芒</div> | |||
| <el-form ref="form" :rules="rulesII" :model="formII"> | |||
| <el-form-item class="phone" prop="phone"> | |||
| <el-input class="phoneInput" v-model="formII.phone"></el-input> | |||
| <div class="inputPhone">请输入您的手机号</div> | |||
| <!-- <el-button class="getCode" type="text" @click="getCode">{{ | |||
| codeInfo | |||
| }}</el-button> --> | |||
| </el-form-item> | |||
| <el-form-item class="code" prop="code"> | |||
| <el-input | |||
| class="codeInput" | |||
| v-model="form.pwd" | |||
| maxlength="10" | |||
| clearable | |||
| ></el-input> | |||
| <div class="inputCode">请输入密码</div> | |||
| </el-form-item> | |||
| <el-form-item class="code" prop="code"> | |||
| <el-input | |||
| class="codeInput" | |||
| v-model="form.code" | |||
| maxlength="10" | |||
| clearable | |||
| ></el-input> | |||
| <div class="inputCode">请输入验证码</div> | |||
| </el-form-item> | |||
| <span class="forgetPwd">忘记密码?</span> | |||
| <el-form-item> | |||
| <el-button class="submitBtn inside" @click="loginByPhoneCode" | |||
| >登录/注册</el-button | |||
| > | |||
| </el-form-item> | |||
| </el-form> | |||
| </div> | |||
| <!-- 用户名密码登录 --> | |||
| <div class="loginBox" v-if="loginType == 3"> | |||
| <div class="welcome">登录邃芒</div> | |||
| <el-form ref="form" :model="formIII"> | |||
| <el-form-item class="code" prop="code"> | |||
| <el-input | |||
| class="codeInput" | |||
| v-model="formIII.inviteCode" | |||
| maxlength="10" | |||
| clearable | |||
| ></el-input> | |||
| <div class="inputCode">请输入您的邀请码</div> | |||
| </el-form-item> | |||
| <el-form-item> | |||
| <el-button class="skipBtn skip" @click="skip">跳过</el-button> | |||
| <el-button class="skipBtn submit" @click="submitInviteCode" | |||
| >确定</el-button | |||
| > | |||
| </el-form-item> | |||
| </el-form> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| // 组件 | |||
| import Vue from "vue"; | |||
| import { Toast } from "vant"; | |||
| import { mapState, mapActions } from "vuex"; | |||
| // 工具 | |||
| import { scrollToID } from "../../utils"; | |||
| // 接口 | |||
| import { | |||
| getCodeByPhone, | |||
| doLoginByPhone, | |||
| doFindInviteCode, | |||
| doUpdateInviteCode, | |||
| } from "../../api/login"; | |||
| Vue.use(Toast); | |||
| export default { | |||
| data() { | |||
| return { | |||
| codeInfo: "获取验证码", | |||
| inPage: false, | |||
| loginType: 1, | |||
| // 短信验证码登录 | |||
| form: { | |||
| phone: "", | |||
| code: "", | |||
| }, | |||
| rules: { | |||
| phone: [ | |||
| { | |||
| required: true, | |||
| trigger: "blur", | |||
| message: "请先输手机号", | |||
| }, | |||
| { | |||
| validator(rule, value, callback, source, options) { | |||
| var errors = []; | |||
| // var mobile = /^1[0|1|2|3|4|5|6|7|8|9]\d{9}$/, | |||
| let phone = /^1[35789]\d{9}$/; | |||
| if (value && !phone.test(value)) { | |||
| callback("抱歉,请输入正确的手机号"); | |||
| } | |||
| callback(errors); | |||
| }, | |||
| }, | |||
| ], | |||
| }, | |||
| // 账号密码登录 | |||
| formII: { | |||
| phone: "", | |||
| pwd: "", | |||
| code: "", | |||
| }, | |||
| rulesII: { | |||
| phone: [ | |||
| { | |||
| required: true, | |||
| trigger: "blur", | |||
| message: "请先输手机号", | |||
| }, | |||
| { | |||
| validator(rule, value, callback, source, options) { | |||
| var errors = []; | |||
| // var mobile = /^1[0|1|2|3|4|5|6|7|8|9]\d{9}$/, | |||
| let phone = /^1[35789]\d{9}$/; | |||
| if (value && !phone.test(value)) { | |||
| callback("抱歉,请输入正确的手机号"); | |||
| } | |||
| callback(errors); | |||
| }, | |||
| }, | |||
| ], | |||
| }, | |||
| // 邀请码 | |||
| formIII: { | |||
| inviteCode: "", | |||
| }, | |||
| }; | |||
| }, | |||
| computed: { | |||
| ...mapState({ | |||
| characters: (state) => state.publicObj.characters, | |||
| }), | |||
| }, | |||
| methods: { | |||
| ...mapActions(["setCharacters"]), | |||
| go(url) { | |||
| this.$router.push(url); | |||
| }, | |||
| // 跳过填写邀请码 | |||
| skip() { | |||
| this.$router.push("/myPage"); | |||
| }, | |||
| // 获取手机短信验证码 | |||
| getCode() { | |||
| if (this.codeInfo != "获取验证码") { | |||
| Toast.fail("请求过于频繁,请稍后再试"); | |||
| return; | |||
| } | |||
| const phoneValue = this.form.phone; | |||
| // 将手机号置入本地存储 | |||
| localStorage.setItem("phoneValue", phoneValue); | |||
| let phoneReg = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/; | |||
| let phoneValide = phoneReg.test(phoneValue); | |||
| if (!phoneValide) { | |||
| Toast.fail("请输入正确的手机号!"); | |||
| } else { | |||
| this.getPhoneCode(phoneValue); | |||
| } | |||
| }, | |||
| // 手机验证码登录 | |||
| loginByPhoneCode() { | |||
| const data = { | |||
| phone: this.form.phone, | |||
| code: this.form.code, | |||
| }; | |||
| this.LoginByPhone(data); | |||
| }, | |||
| // 提交邀请码 | |||
| submitInviteCode() { | |||
| const data = { | |||
| inviteCode: this.formIII.inviteCode, | |||
| }; | |||
| this.updateInviteCode(data); | |||
| }, | |||
| /** | |||
| * @description:获取手机验证码 | |||
| */ | |||
| async getPhoneCode(phone) { | |||
| try { | |||
| const res = await getCodeByPhone(phone); | |||
| Toast.success("短信验证码发送成功!"); | |||
| this.codeInfo = 60; | |||
| const timer = setInterval(() => { | |||
| if (this.codeInfo != 1) { | |||
| this.codeInfo--; | |||
| } else { | |||
| clearInterval(timer); | |||
| this.codeInfo = "获取验证码"; | |||
| } | |||
| }, 1000); | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| } | |||
| }, | |||
| /** | |||
| * @description:短信验证码登录 | |||
| */ | |||
| async LoginByPhone(loginParams) { | |||
| try { | |||
| const res = await doLoginByPhone(loginParams); | |||
| console.log(res, "登录数据"); | |||
| const token = res.data.token; | |||
| // 将token置入本地存储 | |||
| localStorage.setItem("AccessToken", token); | |||
| this.checkInviteCode(); | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| } | |||
| }, | |||
| /** | |||
| * @description:查询用户邀请码状态 | |||
| */ | |||
| async checkInviteCode() { | |||
| try { | |||
| const res = await doFindInviteCode(); | |||
| console.log(res, "查询用户邀请码数据"); | |||
| const status = res.data.status; | |||
| // 当没有邀请码时,切换输入验证码页面 | |||
| if (status == 0) { | |||
| this.loginType = 3; | |||
| // 有邀请码直接前往我的页面 | |||
| } else if (status == 1) { | |||
| Toast.success("登录成功!"); | |||
| this.$router.push("/myPage"); | |||
| } | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| } | |||
| }, | |||
| /** | |||
| * @description:更新邀请码 | |||
| */ | |||
| async updateInviteCode(inviteCodeData) { | |||
| try { | |||
| const res = await doUpdateInviteCode(inviteCodeData); | |||
| console.log(res, "更新邀请码数据"); | |||
| Toast.success("登录成功!"); | |||
| this.$router.push("/myPage"); | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| } | |||
| }, | |||
| }, | |||
| created() { | |||
| // 手机号记忆回填 | |||
| const phoneValue = localStorage.getItem("phoneValue"); | |||
| this.form.phone = phoneValue ? phoneValue : ""; | |||
| }, | |||
| mounted() { | |||
| this.inPage = true; | |||
| scrollToID("top"); | |||
| }, | |||
| }; | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .page { | |||
| opacity: 0; | |||
| transition: all 0.5s; // global-transition | |||
| &.active { | |||
| opacity: 1; | |||
| } | |||
| .logoBox { | |||
| // margin-top: 10px; | |||
| margin-left: 5px; | |||
| margin-top: 10px; | |||
| margin-bottom: 30px; | |||
| overflow: hidden; | |||
| cursor: pointer; | |||
| text-align: center; | |||
| .logo { | |||
| width: 240px; | |||
| height: 70px; | |||
| } | |||
| } | |||
| .loginBox { | |||
| height: 500px; | |||
| // background: linear-gradient(140deg, #6e60e9, #2867d4, #1ec2ae); | |||
| margin: auto; | |||
| text-align: center; | |||
| padding-left: 30px; | |||
| padding-right: 30px; | |||
| .welcome { | |||
| font-size: 18px; | |||
| color: #000; | |||
| font-weight: 600; | |||
| margin-bottom: 40px; | |||
| } | |||
| .phone { | |||
| position: relative; | |||
| margin-bottom: 25px; | |||
| .inputPhone { | |||
| position: absolute; | |||
| background-color: #fff; | |||
| top: -5px; | |||
| left: 12px; | |||
| font-size: 12px; | |||
| height: 10px; | |||
| line-height: 10px; | |||
| color: #0068b7; | |||
| } | |||
| .getCode { | |||
| position: absolute; | |||
| top: 1px; | |||
| right: 10px; | |||
| color: #0068b7; | |||
| } | |||
| } | |||
| .code { | |||
| position: relative; | |||
| .inputCode { | |||
| position: absolute; | |||
| background-color: #fff; | |||
| top: -5px; | |||
| left: 12px; | |||
| font-size: 12px; | |||
| height: 10px; | |||
| line-height: 10px; | |||
| color: #0068b7; | |||
| } | |||
| } | |||
| .submitBtn { | |||
| position: relative; | |||
| right: 10px; | |||
| float: right; | |||
| color: #fff; | |||
| font-size: 15px; | |||
| line-height: 15px; | |||
| border: none; | |||
| padding: 9px; | |||
| background-color: #0068b7; | |||
| border-radius: 5px; | |||
| &.inside { | |||
| top: 10px; | |||
| } | |||
| } | |||
| .skipBtn { | |||
| position: relative; | |||
| top: 10px; | |||
| left: 70px; | |||
| right: 10px; | |||
| width: 78px; | |||
| height: 30px; | |||
| color: #fff; | |||
| font-size: 15px; | |||
| line-height: 15px; | |||
| border: none; | |||
| padding: 9px; | |||
| background-color: #0068b7; | |||
| border-radius: 3px; | |||
| margin-top: 160px; | |||
| &.skip { | |||
| background-color: #a0a0a0; | |||
| } | |||
| } | |||
| .forgetPwd { | |||
| position: relative; | |||
| top: -10px; | |||
| float: left; | |||
| font-size: 12px; | |||
| color: #0068b7; | |||
| } | |||
| } | |||
| } | |||
| ::v-deep .el-input__inner { | |||
| height: 42px; | |||
| border: 1px solid #0068b7; | |||
| } | |||
| </style> | |||
| @@ -1,4 +1,5 @@ | |||
| <template> | |||
| <!-- 手机号13797188591 --> | |||
| <div :class="inPage ? 'page active' : 'page'"> | |||
| <div id="top"></div> | |||
| <div class="logoBox" @click="go('/')"> | |||
| @@ -6,214 +7,347 @@ | |||
| <!-- <div class="logoTitle">metavatar</div> --> | |||
| </div> | |||
| <!-- 短信验证码登录 --> | |||
| <!-- 首页登录 loginType=1 --> | |||
| <div class="loginBox" v-if="loginType == 1"> | |||
| <div class="welcome">登录邃芒</div> | |||
| <el-form ref="form" :rules="rules" :model="form"> | |||
| <!-- 手机号 --> | |||
| <el-form-item class="phone" prop="phone"> | |||
| <el-input class="phoneInput" v-model="form.phone"></el-input> | |||
| <div class="inputPhone">请输入您的手机号</div> | |||
| <el-button class="getCode" type="text" @click="getCode">{{ | |||
| codeInfo | |||
| }}</el-button> | |||
| <el-input | |||
| v-model="form.phone" | |||
| placeholder="请输入您的手机号" | |||
| ></el-input> | |||
| </el-form-item> | |||
| <el-form-item class="code" prop="code"> | |||
| <!-- 密码 --> | |||
| <el-form-item class="code" prop="password"> | |||
| <el-input | |||
| class="codeInput" | |||
| v-model="form.code" | |||
| maxlength="10" | |||
| clearable | |||
| v-model="form.code" | |||
| placeholder="请输入密码" | |||
| ></el-input> | |||
| <div class="inputCode">请输入短信验证码</div> | |||
| </el-form-item> | |||
| <!-- 随机验证码 --> | |||
| <el-form-item class="yzCode" prop="yzCode"> | |||
| <el-col :span="12"> | |||
| <el-input v-model="form.code" placeholder="请输入验证码"></el-input> | |||
| </el-col> | |||
| </el-form-item> | |||
| <!-- 短信登录和忘记密码 --> | |||
| <div class="morePage greenColor"> | |||
| <span @click="loginType=2">短信登录</span> | |||
| <span @click="loginType=3">忘记密码?</span> | |||
| </div> | |||
| <!-- 登录 --> | |||
| <el-form-item> | |||
| <el-button class="submitBtn" @click="loginByPhoneCode" | |||
| >登录/注册</el-button | |||
| > | |||
| >登录/注册</el-button> | |||
| </el-form-item> | |||
| <!-- 没有账号 --> | |||
| <div> | |||
| <span>没有账号?</span> | |||
| <span class="greenColor" @click="loginType=5">立即注册</span> | |||
| </div> | |||
| </el-form> | |||
| </div> | |||
| <!-- 用户名密码登录 --> | |||
| <!-- 短信登录 loginType=2 --> | |||
| <div class="loginBox" v-if="loginType == 2"> | |||
| <div class="welcome">登录邃芒</div> | |||
| <el-form ref="form" :rules="rulesII" :model="formII"> | |||
| <el-form ref="form" :rules="rules" :model="form"> | |||
| <!-- 手机号 --> | |||
| <el-form-item class="phone" prop="phone"> | |||
| <el-input class="phoneInput" v-model="formII.phone"></el-input> | |||
| <div class="inputPhone">请输入您的手机号</div> | |||
| <!-- <el-button class="getCode" type="text" @click="getCode">{{ | |||
| codeInfo | |||
| }}</el-button> --> | |||
| <el-input | |||
| v-model="form.phone" | |||
| placeholder="请输入您的手机号" | |||
| ></el-input> | |||
| </el-form-item> | |||
| <el-form-item class="code" prop="code"> | |||
| <!-- 短信验证码 --> | |||
| <el-form-item class="code" prop="phoneCode"> | |||
| <el-input | |||
| class="codeInput" | |||
| v-model="form.pwd" | |||
| maxlength="10" | |||
| clearable | |||
| v-model="form.code" | |||
| placeholder="请输入短信验证码" | |||
| > | |||
| <div v-if="!countdownState" @click="triggerCountdown" class="greenColor" slot="suffix" type="primary">获取验证码</div> | |||
| <div v-else slot="suffix" type="primary">验证码已发送{{ countNum }}s</div> | |||
| </el-input> | |||
| </el-form-item> | |||
| <!-- 短信登录和忘记密码 --> | |||
| <div class="morePage greenColor inBoxEnd"> | |||
| <span @click="loginType=1">账号登录</span> | |||
| </div> | |||
| <!-- 登录 --> | |||
| <el-form-item> | |||
| <el-button class="submitBtn" @click="loginByPhoneCode" | |||
| >登录</el-button> | |||
| </el-form-item> | |||
| <!-- 没有账号 --> | |||
| <div> | |||
| <span>没有账号?</span> | |||
| <span class="greenColor" @click="loginType=5">立即注册</span> | |||
| </div> | |||
| </el-form> | |||
| </div> | |||
| <!-- 忘记密码 loginType=3--> | |||
| <div class="loginBox" v-if="loginType == 3"> | |||
| <el-form ref="form" :rules="rules" :model="form"> | |||
| <!-- 手机号 --> | |||
| <el-form-item class="phone" prop="phone"> | |||
| <el-input | |||
| v-model="form.phone" | |||
| placeholder="请输入您的手机号" | |||
| ></el-input> | |||
| <div class="inputCode">请输入密码</div> | |||
| </el-form-item> | |||
| <!-- 随机验证码 --> | |||
| <el-form-item class="code" prop="yzCode"> | |||
| <el-col :span="12"> | |||
| <el-input | |||
| maxlength="10" | |||
| clearable | |||
| v-model="form.code" | |||
| placeholder="请输入验证码" | |||
| ></el-input> | |||
| </el-col> | |||
| </el-form-item> | |||
| <!-- 登录 --> | |||
| <el-form-item> | |||
| <el-button class="submitBtn" @click="loginByPhoneCode" | |||
| >获取短信验证码</el-button> | |||
| </el-form-item> | |||
| </el-form> | |||
| </div> | |||
| <el-form-item class="code" prop="code"> | |||
| <!-- 重设密码 loginType=4 --> | |||
| <div class="loginBox" v-if="loginType == 4"> | |||
| <el-form ref="form" :rules="rules" :model="form"> | |||
| <!-- 短信验证码 --> | |||
| <el-form-item class="phone" prop="phoneCode"> | |||
| <el-input | |||
| v-model="form.phone" | |||
| placeholder="请输入短信验证码" | |||
| ></el-input> | |||
| </el-form-item> | |||
| <!-- 新密码1 --> | |||
| <el-form-item class="code" prop="newPassword1"> | |||
| <el-input | |||
| class="codeInput" | |||
| maxlength="10" | |||
| clearable | |||
| v-model="form.code" | |||
| placeholder="请输入您的新密码" | |||
| > | |||
| </el-input> | |||
| </el-form-item> | |||
| <!-- 新密码2 --> | |||
| <el-form-item class="code" prop="newPassword2"> | |||
| <el-input | |||
| maxlength="10" | |||
| clearable | |||
| ></el-input> | |||
| <div class="inputCode">请输入验证码</div> | |||
| v-model="form.code" | |||
| placeholder="请再次确认您的新密码" | |||
| > | |||
| </el-input> | |||
| </el-form-item> | |||
| <span class="forgetPwd">忘记密码?</span> | |||
| <!-- 登录 --> | |||
| <el-form-item> | |||
| <el-button class="submitBtn inside" @click="loginByPhoneCode" | |||
| >登录/注册</el-button | |||
| > | |||
| <el-button class="submitBtn" @click="loginByPhoneCode" | |||
| >保存密码</el-button> | |||
| </el-form-item> | |||
| </el-form> | |||
| </div> | |||
| <!-- 用户名密码登录 --> | |||
| <div class="loginBox" v-if="loginType == 3"> | |||
| <div class="welcome">登录邃芒</div> | |||
| <el-form ref="form" :model="formIII"> | |||
| <el-form-item class="code" prop="code"> | |||
| <!-- 注册 loginType=5 --> | |||
| <div class="loginBox" v-if="loginType == 5"> | |||
| <el-form ref="form" :rules="rules" :model="form"> | |||
| <!-- 短信验证码 --> | |||
| <el-form-item class="phone" prop="phone"> | |||
| <el-input | |||
| v-model="form.phone" | |||
| placeholder="请输入您的手机号" | |||
| ></el-input> | |||
| </el-form-item> | |||
| <!-- 新密码1 --> | |||
| <el-form-item class="code" prop="newPassword1"> | |||
| <el-input | |||
| class="codeInput" | |||
| v-model="formIII.inviteCode" | |||
| maxlength="10" | |||
| clearable | |||
| ></el-input> | |||
| <div class="inputCode">请输入您的邀请码</div> | |||
| v-model="form.code" | |||
| placeholder="请输入您的密码" | |||
| > | |||
| </el-input> | |||
| </el-form-item> | |||
| <el-form-item> | |||
| <el-button class="skipBtn skip" @click="skip">跳过</el-button> | |||
| <el-button class="skipBtn submit" @click="submitInviteCode" | |||
| >确定</el-button | |||
| <!-- 新密码2 --> | |||
| <el-form-item class="code" prop="newPassword2"> | |||
| <el-input | |||
| maxlength="10" | |||
| clearable | |||
| v-model="form.code" | |||
| placeholder="请再次确认您的密码" | |||
| > | |||
| </el-input> | |||
| </el-form-item> | |||
| <!-- 注册 --> | |||
| <el-form-item> | |||
| <el-button class="submitBtn" @click="loginByPhoneCode" | |||
| >注册</el-button> | |||
| </el-form-item> | |||
| </el-form> | |||
| </div> | |||
| <!-- 弹出层 --> | |||
| <van-popup v-model="showDialog">内容</van-popup> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| // 组件 | |||
| import Vue from "vue"; | |||
| import { Toast } from "vant"; | |||
| import { mapState, mapActions } from "vuex"; | |||
| import Vue from 'vue' | |||
| import { Toast } from 'vant' | |||
| import { mapState, mapActions } from 'vuex' | |||
| // 工具 | |||
| import { scrollToID } from "../../utils"; | |||
| import { scrollToID } from '../../utils' | |||
| // 接口 | |||
| import { | |||
| getCodeByPhone, | |||
| doLoginByPhone, | |||
| doFindInviteCode, | |||
| doUpdateInviteCode, | |||
| } from "../../api/login"; | |||
| doUpdateInviteCode | |||
| } from '../../api/login' | |||
| Vue.use(Toast); | |||
| Vue.use(Toast) | |||
| export default { | |||
| data() { | |||
| return { | |||
| codeInfo: "获取验证码", | |||
| showDialog:false,//弹出层状态 | |||
| countNum: 60,// 倒计时 | |||
| countdownState:false,//倒计时状态 | |||
| codeInfo: '获取验证码', | |||
| inPage: false, | |||
| loginType: 1, | |||
| loginType: 1, //显示页面字符 | |||
| // 短信验证码登录 | |||
| form: { | |||
| phone: "", | |||
| code: "", | |||
| phone: '', | |||
| password: '', | |||
| newPassword1:'', | |||
| newPassword2:'', | |||
| phoneCode:'', | |||
| code: '', | |||
| yzCode: '' | |||
| }, | |||
| rules: { | |||
| phone: [ | |||
| { | |||
| required: true, | |||
| trigger: "blur", | |||
| message: "请先输手机号", | |||
| trigger: 'blur', | |||
| message: '请先输手机号' | |||
| }, | |||
| { | |||
| validator(rule, value, callback, source, options) { | |||
| var errors = []; | |||
| var errors = [] | |||
| // var mobile = /^1[0|1|2|3|4|5|6|7|8|9]\d{9}$/, | |||
| let phone = /^1[35789]\d{9}$/; | |||
| let phone = /^1[35789]\d{9}$/ | |||
| if (value && !phone.test(value)) { | |||
| callback("抱歉,请输入正确的手机号"); | |||
| callback('抱歉,请输入正确的手机号') | |||
| } | |||
| callback(errors); | |||
| }, | |||
| }, | |||
| ], | |||
| callback(errors) | |||
| } | |||
| } | |||
| ] | |||
| }, | |||
| // 账号密码登录 | |||
| formII: { | |||
| phone: "", | |||
| pwd: "", | |||
| code: "", | |||
| phone: '', | |||
| pwd: '', | |||
| code: '' | |||
| }, | |||
| rulesII: { | |||
| phone: [ | |||
| { | |||
| required: true, | |||
| trigger: "blur", | |||
| message: "请先输手机号", | |||
| trigger: 'blur', | |||
| message: '请先输手机号' | |||
| }, | |||
| { | |||
| validator(rule, value, callback, source, options) { | |||
| var errors = []; | |||
| var errors = [] | |||
| // var mobile = /^1[0|1|2|3|4|5|6|7|8|9]\d{9}$/, | |||
| let phone = /^1[35789]\d{9}$/; | |||
| let phone = /^1[35789]\d{9}$/ | |||
| if (value && !phone.test(value)) { | |||
| callback("抱歉,请输入正确的手机号"); | |||
| callback('抱歉,请输入正确的手机号') | |||
| } | |||
| callback(errors); | |||
| }, | |||
| }, | |||
| ], | |||
| callback(errors) | |||
| } | |||
| } | |||
| ] | |||
| }, | |||
| // 短信登录 | |||
| // 忘记密码 | |||
| // 重设密码 | |||
| // 注册 | |||
| // 邀请码 | |||
| formIII: { | |||
| inviteCode: "", | |||
| }, | |||
| }; | |||
| inviteCode: '' | |||
| } | |||
| } | |||
| }, | |||
| computed: { | |||
| ...mapState({ | |||
| characters: (state) => state.publicObj.characters, | |||
| }), | |||
| characters: (state) => state.publicObj.characters | |||
| }) | |||
| }, | |||
| methods: { | |||
| ...mapActions(["setCharacters"]), | |||
| ...mapActions(['setCharacters']), | |||
| // 发送短信验证码 | |||
| triggerCountdown() { | |||
| //调用接口 | |||
| this.getCode() | |||
| // 切换文字 | |||
| this.countdownState = !this.countdownState; | |||
| // 定时器 | |||
| let intervalBtn = setInterval(() => { | |||
| // 倒数自减 | |||
| this.countNum--; | |||
| if(this.countNum < 0) { | |||
| // 清除定时器 | |||
| clearInterval(intervalBtn) | |||
| // 更改状态 | |||
| this.countdownState =! this.countdownState; | |||
| // 重置倒计时状态 | |||
| this.countNum = 60; | |||
| }; | |||
| // 倒计时 | |||
| }, 1000); | |||
| }, | |||
| go(url) { | |||
| this.$router.push(url); | |||
| this.$router.push(url) | |||
| }, | |||
| // 跳过填写邀请码 | |||
| skip() { | |||
| this.$router.push("/myPage"); | |||
| this.$router.push('/myPage') | |||
| }, | |||
| // 获取手机短信验证码 | |||
| getCode() { | |||
| if (this.codeInfo != "获取验证码") { | |||
| Toast.fail("请求过于频繁,请稍后再试"); | |||
| return; | |||
| if (this.codeInfo != '获取验证码') { | |||
| Toast.fail('请求过于频繁,请稍后再试') | |||
| return | |||
| } | |||
| const phoneValue = this.form.phone; | |||
| const phoneValue = this.form.phone | |||
| // 将手机号置入本地存储 | |||
| localStorage.setItem("phoneValue", phoneValue); | |||
| let phoneReg = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/; | |||
| let phoneValide = phoneReg.test(phoneValue); | |||
| localStorage.setItem('phoneValue', phoneValue) | |||
| let phoneReg = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/ | |||
| let phoneValide = phoneReg.test(phoneValue) | |||
| if (!phoneValide) { | |||
| Toast.fail("请输入正确的手机号!"); | |||
| Toast.fail('请输入正确的手机号!') | |||
| } else { | |||
| this.getPhoneCode(phoneValue); | |||
| this.getPhoneCode(phoneValue) | |||
| } | |||
| }, | |||
| @@ -221,17 +355,17 @@ export default { | |||
| loginByPhoneCode() { | |||
| const data = { | |||
| phone: this.form.phone, | |||
| code: this.form.code, | |||
| }; | |||
| this.LoginByPhone(data); | |||
| code: this.form.code | |||
| } | |||
| this.LoginByPhone(data) | |||
| }, | |||
| // 提交邀请码 | |||
| submitInviteCode() { | |||
| const data = { | |||
| inviteCode: this.formIII.inviteCode, | |||
| }; | |||
| this.updateInviteCode(data); | |||
| inviteCode: this.formIII.inviteCode | |||
| } | |||
| this.updateInviteCode(data) | |||
| }, | |||
| /** | |||
| @@ -239,20 +373,20 @@ export default { | |||
| */ | |||
| async getPhoneCode(phone) { | |||
| try { | |||
| const res = await getCodeByPhone(phone); | |||
| Toast.success("短信验证码发送成功!"); | |||
| this.codeInfo = 60; | |||
| const res = await getCodeByPhone(phone) | |||
| Toast.success('短信验证码发送成功!') | |||
| this.codeInfo = 60 | |||
| const timer = setInterval(() => { | |||
| if (this.codeInfo != 1) { | |||
| this.codeInfo--; | |||
| this.codeInfo-- | |||
| } else { | |||
| clearInterval(timer); | |||
| this.codeInfo = "获取验证码"; | |||
| clearInterval(timer) | |||
| this.codeInfo = '获取验证码' | |||
| } | |||
| }, 1000); | |||
| }, 1000) | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| console.log(error, 'error') | |||
| Toast.fail(error.message) | |||
| } | |||
| }, | |||
| @@ -261,15 +395,15 @@ export default { | |||
| */ | |||
| async LoginByPhone(loginParams) { | |||
| try { | |||
| const res = await doLoginByPhone(loginParams); | |||
| console.log(res, "登录数据"); | |||
| const token = res.data.token; | |||
| const res = await doLoginByPhone(loginParams) | |||
| console.log(res, '登录数据') | |||
| const token = res.data.token | |||
| // 将token置入本地存储 | |||
| localStorage.setItem("AccessToken", token); | |||
| this.checkInviteCode(); | |||
| localStorage.setItem('AccessToken', token) | |||
| this.checkInviteCode() | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| console.log(error, 'error') | |||
| Toast.fail(error.message) | |||
| } | |||
| }, | |||
| @@ -278,20 +412,20 @@ export default { | |||
| */ | |||
| async checkInviteCode() { | |||
| try { | |||
| const res = await doFindInviteCode(); | |||
| console.log(res, "查询用户邀请码数据"); | |||
| const status = res.data.status; | |||
| const res = await doFindInviteCode() | |||
| console.log(res, '查询用户邀请码数据') | |||
| const status = res.data.status | |||
| // 当没有邀请码时,切换输入验证码页面 | |||
| if (status == 0) { | |||
| this.loginType = 3; | |||
| this.loginType = 3 | |||
| // 有邀请码直接前往我的页面 | |||
| } else if (status == 1) { | |||
| Toast.success("登录成功!"); | |||
| this.$router.push("/myPage"); | |||
| Toast.success('登录成功!') | |||
| this.$router.push('/myPage') | |||
| } | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| console.log(error, 'error') | |||
| Toast.fail(error.message) | |||
| } | |||
| }, | |||
| @@ -300,29 +434,32 @@ export default { | |||
| */ | |||
| async updateInviteCode(inviteCodeData) { | |||
| try { | |||
| const res = await doUpdateInviteCode(inviteCodeData); | |||
| console.log(res, "更新邀请码数据"); | |||
| Toast.success("登录成功!"); | |||
| this.$router.push("/myPage"); | |||
| const res = await doUpdateInviteCode(inviteCodeData) | |||
| console.log(res, '更新邀请码数据') | |||
| Toast.success('登录成功!') | |||
| this.$router.push('/myPage') | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| console.log(error, 'error') | |||
| Toast.fail(error.message) | |||
| } | |||
| }, | |||
| } | |||
| }, | |||
| created() { | |||
| // 手机号记忆回填 | |||
| const phoneValue = localStorage.getItem("phoneValue"); | |||
| this.form.phone = phoneValue ? phoneValue : ""; | |||
| const phoneValue = localStorage.getItem('phoneValue') | |||
| this.form.phone = phoneValue ? phoneValue : '' | |||
| }, | |||
| mounted() { | |||
| this.inPage = true; | |||
| scrollToID("top"); | |||
| }, | |||
| }; | |||
| this.inPage = true | |||
| scrollToID('top') | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .greenColor { | |||
| color: #5ed5c8; | |||
| } | |||
| .page { | |||
| opacity: 0; | |||
| transition: all 0.5s; // global-transition | |||
| @@ -332,8 +469,8 @@ export default { | |||
| .logoBox { | |||
| // margin-top: 10px; | |||
| margin-left: 5px; | |||
| margin-top: 10px; | |||
| margin-bottom: 30px; | |||
| margin-top: 25px; | |||
| margin-bottom: 25px; | |||
| overflow: hidden; | |||
| cursor: pointer; | |||
| text-align: center; | |||
| @@ -356,20 +493,14 @@ export default { | |||
| font-weight: 600; | |||
| margin-bottom: 40px; | |||
| } | |||
| .inBoxEnd { | |||
| display: flex; | |||
| justify-content: end !important; | |||
| } | |||
| .phone { | |||
| position: relative; | |||
| margin-bottom: 25px; | |||
| .inputPhone { | |||
| position: absolute; | |||
| background-color: #fff; | |||
| top: -5px; | |||
| left: 12px; | |||
| font-size: 12px; | |||
| height: 10px; | |||
| line-height: 10px; | |||
| color: #0068b7; | |||
| } | |||
| .getCode { | |||
| position: absolute; | |||
| top: 1px; | |||
| @@ -390,18 +521,34 @@ export default { | |||
| color: #0068b7; | |||
| } | |||
| } | |||
| .morePage { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| margin-top: -9px; | |||
| } | |||
| .submitBtn { | |||
| position: relative; | |||
| right: 10px; | |||
| float: right; | |||
| // right: 10px; | |||
| // float: right; | |||
| color: #fff; | |||
| font-size: 15px; | |||
| line-height: 15px; | |||
| border: none; | |||
| margin-top: 25px; | |||
| // margin-bottom: 7.5px; | |||
| padding: 9px; | |||
| background-color: #0068b7; | |||
| border-radius: 5px; | |||
| background-image: linear-gradient( | |||
| 316deg, | |||
| rgba(110, 228, 215, 1) 0, | |||
| rgba(55, 196, 241, 1) 31.975823%, | |||
| rgba(164, 154, 252, 1) 100% | |||
| ); | |||
| border-radius: 25px; | |||
| width: 315px; | |||
| height: 50px; | |||
| // padding: 12px 138px 12px 138px; | |||
| &.inside { | |||
| top: 10px; | |||
| } | |||
| @@ -436,6 +583,10 @@ export default { | |||
| } | |||
| ::v-deep .el-input__inner { | |||
| height: 42px; | |||
| border: 1px solid #0068b7; | |||
| border: 0px; | |||
| background-color: #f6f6f6; | |||
| } | |||
| ::v-deep .el-form-item { | |||
| margin-bottom: 25px; | |||
| } | |||
| </style> | |||
| @@ -0,0 +1,312 @@ | |||
| <template> | |||
| <div :class="inPage ? 'page active' : 'page'"> | |||
| <div id="top"></div> | |||
| <HeadTop /> | |||
| <!-- <div class="chooseModel"> | |||
| <div :class="phase == 1 ? 'active' : ''">选择模板</div> | |||
| <div :class="phase == 2 ? 'active' : ''">录入文案</div> | |||
| <div :class="phase == 3 ? 'active' : ''">合成视频</div> | |||
| </div> --> | |||
| <div class="title">选择模板</div> | |||
| <div class="typeOutSide"> | |||
| <div class="type"> | |||
| <div :class="type == 0 ? 'active' : ''" @click="chooseType(0)"> | |||
| 全部模板 | |||
| </div> | |||
| <div :class="type == 2 ? 'active' : ''" @click="chooseType(2)"> | |||
| 女性模板 | |||
| </div> | |||
| <div :class="type == 1 ? 'active' : ''" @click="chooseType(1)"> | |||
| 男性模板 | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="choose"> | |||
| <div class="modeList"> | |||
| <div | |||
| class="model" | |||
| :class="currentId == item.id ? 'active' : ''" | |||
| v-if="modeList.length >= 1" | |||
| v-for="(item, index) in modeList" | |||
| :key="index" | |||
| @click="selectModel(item.id)" | |||
| > | |||
| <img :src="item.coverImg" alt="" /> | |||
| <div class="modelName">{{ item.title }}</div> | |||
| <div class="setPaper">录入文案</div> | |||
| </div> | |||
| <div class="alt" v-if="modeList.length == 0">暂无可用模板</div> | |||
| </div> | |||
| </div> | |||
| <div class="blank" v-if="modeList.length <= 2"></div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import Vue from "vue"; | |||
| import { mapState, mapActions } from "vuex"; | |||
| import HeadTop from "./../../components/common/head.vue"; | |||
| import { Toast } from "vant"; | |||
| import { scrollToID } from "../../utils"; | |||
| import { | |||
| getModeList, | |||
| getModeDetailById, | |||
| saveOrUpdateUserVideo, | |||
| } from "../../api/chooseModel"; | |||
| Vue.use(Toast); | |||
| export default { | |||
| components: { | |||
| HeadTop, | |||
| }, | |||
| data() { | |||
| return { | |||
| inPage: false, | |||
| type: 0, | |||
| currentId: "", | |||
| modeList: [], // 模板列表 | |||
| }; | |||
| }, | |||
| computed: { | |||
| ...mapState({ | |||
| characters: (state) => state.publicObj.characters, | |||
| }), | |||
| }, | |||
| methods: { | |||
| ...mapActions(["setCharacters"]), | |||
| globalWatcher(e) { | |||
| console.log(e, "e"); | |||
| }, | |||
| go(url) { | |||
| this.$router.push(url); | |||
| }, | |||
| chooseModel(num) { | |||
| this.phase = num; | |||
| }, | |||
| chooseType(num) { | |||
| this.type = num; | |||
| this.loadModeList(num); | |||
| }, | |||
| selectModel(id) { | |||
| if (this.currentId != id) { | |||
| this.currentId = id; | |||
| } else { | |||
| this.getModeDetail(id); | |||
| } | |||
| }, | |||
| // 获取模板列表 | |||
| async loadModeList(sex) { | |||
| try { | |||
| sex = sex == 0 ? "" : sex; | |||
| const res = await getModeList(sex); | |||
| console.log(res, "获取模板列表"); | |||
| this.modeList = res.data.list; | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| } | |||
| }, | |||
| async getModeDetail(id) { | |||
| try { | |||
| const res = await getModeDetailById(id); | |||
| console.log(res, "根据id获取模板详情"); | |||
| const modelDetail = res.data; | |||
| this.goSetPaperWork(modelDetail); | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| } | |||
| }, | |||
| async saveToSetPaper(data, modelDetail) { | |||
| try { | |||
| const res = await saveOrUpdateUserVideo(data); | |||
| console.log(res, "保存或修改用户作品"); | |||
| this.$router.push({ | |||
| path: "/getPaper", | |||
| query: { | |||
| modelDetail: JSON.stringify(modelDetail), | |||
| saveID: res.data.id, | |||
| }, | |||
| }); | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| } | |||
| }, | |||
| /** | |||
| * @description:根据模板详情跳转至选择文案 | |||
| * @param {type}modelDetail | |||
| * @event:Go page => setPaperWork | |||
| */ | |||
| goSetPaperWork(modelDetail) { | |||
| const data = { | |||
| // id: "", | |||
| type: 1, | |||
| personMouldId: modelDetail.id, //模板id | |||
| personMouldSmId: modelDetail.mouldSmId, //模板标识 | |||
| // voiceMouldId: "", | |||
| // voiceMouldId: "", | |||
| }; | |||
| this.saveToSetPaper(data, modelDetail); | |||
| }, | |||
| }, | |||
| mounted() { | |||
| this.inPage = true; | |||
| scrollToID("top"); | |||
| }, | |||
| created() { | |||
| this.loadModeList(2); | |||
| }, | |||
| }; | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .page { | |||
| transform: translateX(30%); | |||
| opacity: 0; | |||
| transition: all 0.5s; // global-transition | |||
| padding-bottom: 25px; | |||
| &.active { | |||
| opacity: 1; | |||
| transform: translateX(0); | |||
| } | |||
| .chooseModel { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| width: 350px; | |||
| height: 32px; | |||
| margin: auto; | |||
| margin-top: 15px; | |||
| margin-bottom: 15px; | |||
| div { | |||
| width: 33.33%; | |||
| height: 100%; | |||
| line-height: 32px; | |||
| text-align: center; | |||
| border: 1px solid #46464661; | |||
| &.active { | |||
| background-color: #00ccff; | |||
| color: #fff; | |||
| } | |||
| } | |||
| } | |||
| .title { | |||
| text-align: center; | |||
| width: 70px; | |||
| font-size: 16px; | |||
| font-weight: 600; | |||
| border-bottom: 3px solid #0068b7; | |||
| padding-bottom: 7px; | |||
| margin: 10px auto; | |||
| margin-bottom: 25px; | |||
| } | |||
| .typeOutSide { | |||
| position: sticky; | |||
| top: 60px; | |||
| z-index: 99; | |||
| .type { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| padding: 0 25px; | |||
| margin-bottom: 20px; | |||
| div { | |||
| width: 94px; | |||
| height: 35px; | |||
| line-height: 35px; | |||
| color: #fff; | |||
| border: 1px solid #bfbfbf; | |||
| background-color: #bfbfbf; | |||
| border-radius: 5px; | |||
| text-align: center; | |||
| transition: all 0.3s; | |||
| &.active { | |||
| color: #fff; | |||
| border: 1px solid #0068b7; | |||
| background-color: #0068b7; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .choose { | |||
| margin-bottom: 40px; | |||
| .modeList { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| flex-wrap: wrap; | |||
| margin: auto; | |||
| padding: 0 10px; | |||
| .model { | |||
| position: relative; | |||
| text-align: left; | |||
| margin-bottom: 25px; | |||
| border: 1px solid #00000028; | |||
| padding: 8px; | |||
| border-radius: 8px; | |||
| transition: all 0.3s; | |||
| opacity: 0.9; | |||
| img { | |||
| width: 150px; | |||
| height: 220px; | |||
| } | |||
| .modelName { | |||
| margin-top: 4px; | |||
| font-size: 13px; | |||
| } | |||
| .setPaper { | |||
| position: absolute; | |||
| top: 80%; | |||
| left: 50%; | |||
| transform: translate(-50%, -50%); | |||
| color: #fff; | |||
| font-size: 14px; | |||
| font-weight: 600; | |||
| background-color: #00000042; | |||
| padding: 3px 5px; | |||
| border-radius: 5px; | |||
| transition: all 0.3s; | |||
| opacity: 0; | |||
| } | |||
| &.active { | |||
| transform: translateY(-3px); | |||
| box-shadow: #60606082 0px 2px 2px 1px; | |||
| opacity: 1; | |||
| .setPaper { | |||
| opacity: 1; | |||
| } | |||
| } | |||
| } | |||
| .alt { | |||
| font-size: 18px; | |||
| margin: 80px auto; | |||
| height: 450px; | |||
| line-height: 450px; | |||
| } | |||
| } | |||
| } | |||
| .blank { | |||
| width: 1px; | |||
| height: 1px; | |||
| margin-bottom: 240px; | |||
| } | |||
| } | |||
| </style> | |||
| @@ -2,11 +2,11 @@ | |||
| <div :class="inPage ? 'page active' : 'page'"> | |||
| <div id="top"></div> | |||
| <HeadTop /> | |||
| <!-- <div class="chooseModel"> | |||
| <div :class="phase == 1 ? 'active' : ''">选择模板</div> | |||
| <div :class="phase == 2 ? 'active' : ''">录入文案</div> | |||
| <div :class="phase == 3 ? 'active' : ''">合成视频</div> | |||
| </div> --> | |||
| <!-- 顶部tab栏 --> | |||
| <van-tabs animated color="#7264F5" line-width=46 line-height=6 title-inactive-color="#666" title-active-color="#333"> | |||
| <van-tab v-for="item in tabList" :key="item.id" :title="item.name"> | |||
| </van-tab> | |||
| </van-tabs> | |||
| <div class="title">选择模板</div> | |||
| <div class="typeOutSide"> | |||
| @@ -22,7 +22,7 @@ | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <!-- 模板列表 --> | |||
| <div class="choose"> | |||
| <div class="modeList"> | |||
| <div | |||
| @@ -67,6 +67,15 @@ export default { | |||
| type: 0, | |||
| currentId: "", | |||
| modeList: [], // 模板列表 | |||
| tabList: [ | |||
| { id: 1, name: '全部' }, | |||
| { id: 2, name: '男性' }, | |||
| { id: 3, name: '女性' }, | |||
| { id: 4, name: '原P' }, | |||
| { id: 5, name: '武装直升机' }, | |||
| { id: 6, name: '粥P' }, | |||
| { id: 7, name: '二刺猿' }, | |||
| ] | |||
| }; | |||
| }, | |||
| computed: { | |||
| @@ -115,13 +124,20 @@ export default { | |||
| Toast.fail(error.message); | |||
| } | |||
| }, | |||
| // 根据id获取模板详情 | |||
| async getModeDetail(id) { | |||
| try { | |||
| const res = await getModeDetailById(id); | |||
| console.log(res, "根据id获取模板详情"); | |||
| const modelDetail = res.data; | |||
| this.goSetPaperWork(modelDetail); | |||
| this.$router.push({ | |||
| path: '/previewModel', | |||
| query: { | |||
| imgUrl: res.data.coverImg, | |||
| modelId:res.data.id } | |||
| }) | |||
| // this.goSetPaperWork(modelDetail); | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| @@ -132,13 +148,13 @@ export default { | |||
| try { | |||
| const res = await saveOrUpdateUserVideo(data); | |||
| console.log(res, "保存或修改用户作品"); | |||
| this.$router.push({ | |||
| path: "/getPaper", | |||
| query: { | |||
| modelDetail: JSON.stringify(modelDetail), | |||
| saveID: res.data.id, | |||
| }, | |||
| }); | |||
| // this.$router.push({ | |||
| // path: "/getPaper", | |||
| // query: { | |||
| // modelDetail: JSON.stringify(modelDetail), | |||
| // saveID: res.data.id, | |||
| // }, | |||
| // }); | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| @@ -173,6 +189,10 @@ export default { | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| ::v-deep .van-tab--active { | |||
| font-size: 17px; | |||
| font-weight: 700; | |||
| } | |||
| .page { | |||
| transform: translateX(30%); | |||
| opacity: 0; | |||
| @@ -253,24 +273,27 @@ export default { | |||
| align-items: center; | |||
| flex-wrap: wrap; | |||
| margin: auto; | |||
| padding: 0 10px; | |||
| padding: 0 23px; | |||
| .model { | |||
| position: relative; | |||
| text-align: left; | |||
| margin-bottom: 25px; | |||
| border: 1px solid #00000028; | |||
| padding: 8px; | |||
| border-radius: 8px; | |||
| margin-bottom: 15px; | |||
| // border: 1px solid #00000028; | |||
| // padding: 8px; | |||
| width: 154px; | |||
| height: 305px; | |||
| transition: all 0.3s; | |||
| opacity: 0.9; | |||
| img { | |||
| width: 150px; | |||
| height: 220px; | |||
| border-radius: 8px; | |||
| width: 100%; | |||
| height: 273px; | |||
| } | |||
| .modelName { | |||
| margin-top: 4px; | |||
| font-size: 13px; | |||
| margin-top: 10px; | |||
| font-weight: 700; | |||
| font-size: 16px; | |||
| } | |||
| .setPaper { | |||
| position: absolute; | |||
| @@ -0,0 +1,150 @@ | |||
| <template> | |||
| <div :class="inPage ? 'page active' : 'page'"> | |||
| <div id="top"></div> | |||
| <HeadTop /> | |||
| <div class="content"> | |||
| <!-- 展示图片 --> | |||
| <div v-if="imgUrl" class="shouModelImg"> | |||
| <img :src="imgUrl" alt=""> | |||
| </div> | |||
| <!-- 文字 --> | |||
| <div class="addText"> | |||
| <div class="addText-title">添加文案</div> | |||
| <div class="desalinate"> | |||
| <span>已录入65字</span> | |||
| <span>视频时长: 00:16</span> | |||
| </div> | |||
| </div> | |||
| <!-- 标题框 --> | |||
| <div class="textInput"> | |||
| <!-- 标题 --> | |||
| <el-input v-model="inputTitle" placeholder="请输入标题"></el-input> | |||
| <div class="divider" /> | |||
| <!-- 语音内容 --> | |||
| <el-input type="textarea" v-model="textareaContent"></el-input> | |||
| </div> | |||
| <!-- 播报声音 --> | |||
| <div class="addText"> | |||
| <div class="addText-title">播报声音<span class="redWord">(必选)</span></div> | |||
| <div> | |||
| 英语_女性_安娜 | |||
| </div> | |||
| </div> | |||
| <!-- 合成按钮 --> | |||
| <div class="makeVideo" >立即制作</div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| // 组件 | |||
| import Vue from "vue"; | |||
| import { Toast } from "vant"; | |||
| import { mapState, mapActions } from "vuex"; | |||
| import HeadTop from "./../../components/common/head.vue"; | |||
| // 工具 | |||
| import { scrollToID } from "../../utils"; | |||
| Vue.use(Toast); | |||
| export default { | |||
| components: { | |||
| HeadTop, | |||
| }, | |||
| data() { | |||
| return { | |||
| inPage: false, | |||
| imgUrl:null, | |||
| modelId: null, | |||
| inputTitle: '', | |||
| textareaContent:'' | |||
| }; | |||
| }, | |||
| computed: { | |||
| ...mapState({ | |||
| characters: (state) => state.publicObj.characters, | |||
| }), | |||
| }, | |||
| methods: { | |||
| ...mapActions(["setCharacters"]), | |||
| go(url) { | |||
| this.$router.push(url); | |||
| }, | |||
| }, | |||
| created() { | |||
| this.imgUrl=this.$route.query.imgUrl | |||
| this.modelId=this.$route.query.modelId | |||
| }, | |||
| mounted() { | |||
| this.inPage = true; | |||
| scrollToID("top"); | |||
| }, | |||
| }; | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .page { | |||
| transform: translateX(30%); | |||
| opacity: 0; | |||
| transition: all 0.5s; // global-transition | |||
| &.active { | |||
| opacity: 1; | |||
| transform: translateX(0); | |||
| } | |||
| } | |||
| .content { | |||
| padding: 0 10px; | |||
| width: 375px; | |||
| .shouModelImg { | |||
| display: flex; | |||
| justify-content: center ; | |||
| width: 100%; | |||
| img { | |||
| width: 200px; | |||
| height: 351px; | |||
| } | |||
| } | |||
| .addText { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| margin-top: 20px; | |||
| &-title { | |||
| font-size: 16px; | |||
| font-weight: 600; | |||
| color: #000; | |||
| } | |||
| } | |||
| .textInput { | |||
| margin-top: 10px; | |||
| width: 100%; | |||
| border: 1px solid; | |||
| border-image: linear-gradient(225deg, rgba(81, 217, 202, 1), rgba(114, 100, 245, 1)) 1 1; | |||
| border-radius: 6px; | |||
| .divider { | |||
| transform: scaleY (0.25); | |||
| width: 100%; | |||
| height: 1px; | |||
| border-top: 1px solid; | |||
| border-image: linear-gradient(225deg, rgba(81, 217, 202, 1), rgba(114, 100, 245, 1)) 1 1; | |||
| } | |||
| ::v-deep .el-input__inner { | |||
| border: none; | |||
| } | |||
| ::v-deep .el-textarea__inner { | |||
| border: none; | |||
| } | |||
| } | |||
| .makeVideo { | |||
| margin: 15px 20px 0; | |||
| width: 315px; | |||
| height: 50px; | |||
| text-align: center; | |||
| font-size: 20px; | |||
| line-height: 50px; | |||
| color: #fff; | |||
| background: linear-gradient(316deg, #6EE4D7 0%, #37C4F1 32%, #A49AFC 100%); | |||
| border-radius: 25px; | |||
| } | |||
| } | |||
| </style> | |||
| @@ -0,0 +1,98 @@ | |||
| <template> | |||
| <div :class="inPage ? 'page active' : 'page'"> | |||
| <div id="top"></div> | |||
| <HeadTop /> | |||
| <!-- 展示图片 --> | |||
| <div v-if="imgUrl" class="shouModelImg"> | |||
| <img :src="imgUrl" alt=""> | |||
| </div> | |||
| <div class="makeMpdel" @click="handleMakeMpdel">立即制作</div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| // 组件 | |||
| import Vue from "vue"; | |||
| import { Toast } from "vant"; | |||
| import { mapState, mapActions } from "vuex"; | |||
| // 工具 | |||
| import { scrollToID } from "../../utils"; | |||
| import HeadTop from "./../../components/common/head.vue"; | |||
| Vue.use(Toast); | |||
| export default { | |||
| components: { | |||
| HeadTop, | |||
| }, | |||
| data() { | |||
| return { | |||
| inPage: false, | |||
| imgUrl: null, | |||
| modelId:null | |||
| }; | |||
| }, | |||
| computed: { | |||
| ...mapState({ | |||
| characters: (state) => state.publicObj.characters, | |||
| }), | |||
| }, | |||
| methods: { | |||
| ...mapActions(["setCharacters"]), | |||
| // 点击立即制作 | |||
| handleMakeMpdel() { | |||
| this.$router.push({ | |||
| path: '/editModel', | |||
| query: { | |||
| imgUrl: this.imgUrl, | |||
| modelId: this.modelId | |||
| } | |||
| }) | |||
| }, | |||
| go(url) { | |||
| this.$router.push(url); | |||
| }, | |||
| }, | |||
| created() { | |||
| this.imgUrl=this.$route.query.imgUrl | |||
| this.modelId=this.$route.query.modelId | |||
| }, | |||
| mounted() { | |||
| this.inPage = true; | |||
| scrollToID("top"); | |||
| }, | |||
| }; | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .page { | |||
| transform: translateX(30%); | |||
| opacity: 0; | |||
| transition: all 0.5s; // global-transition | |||
| &.active { | |||
| opacity: 1; | |||
| transform: translateX(0); | |||
| } | |||
| } | |||
| .shouModelImg { | |||
| padding: 20px 30px; | |||
| img { | |||
| width: 315px; | |||
| height: 518px; | |||
| border-radius: 10px; | |||
| } | |||
| } | |||
| .makeMpdel { | |||
| margin-left: 30px; | |||
| width: 315px; | |||
| height: 50px; | |||
| text-align: center; | |||
| font-size: 20px; | |||
| line-height: 50px; | |||
| color: #fff; | |||
| background: linear-gradient(316deg, #6EE4D7 0%, #37C4F1 32%, #A49AFC 100%); | |||
| border-radius: 25px; | |||
| } | |||
| </style> | |||
| @@ -0,0 +1,489 @@ | |||
| <template> | |||
| <div :class="inPage ? 'page active' : 'page'"> | |||
| <div id="top"></div> | |||
| <HeadTop /> | |||
| <!-- 顶部图 --> | |||
| <img class="showIMG" src="../../assets/img/BG-Page.png" alt="" /> | |||
| <!-- 展示列表 --> | |||
| <div class="item"> | |||
| <div class="title"> | |||
| <img src="../../assets/img/myVideo.png" alt=""> | |||
| 我的视频作品 | |||
| <span class="floatRight" style="float: right;">草稿箱</span> | |||
| </div> | |||
| <!-- 具体内容 --> | |||
| <MyVideoItem :videoList="videoList"/> | |||
| </div> | |||
| <!-- 分页 --> | |||
| <van-pagination | |||
| v-model="currentPage" | |||
| :total-items="total" | |||
| :items-per-page="4" | |||
| @change="pageChange" | |||
| /> | |||
| <div class="goAdd" @click="checkInviteCode">+ 创作新作品</div> | |||
| <div | |||
| class="messageCover" | |||
| :class="isShowMessageCover ? 'active' : ''" | |||
| @click="exitCover" | |||
| > | |||
| <div class="message" id="message"> | |||
| <div class="connect" id="message">请添加微信与我们联系</div> | |||
| <div class="qrCode" id="message"> | |||
| <img src="../../assets/img/SuiMangQRCode.png" alt="" /> | |||
| </div> | |||
| <div class="phoneNum" id="message">或致电13260039498</div> | |||
| <div class="clickToClose">点击空白处关闭</div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| // 组件 | |||
| import Vue from "vue"; | |||
| import { Toast, Dialog } from "vant"; | |||
| import { mapState, mapActions } from "vuex"; | |||
| import HeadTop from "./../../components/common/head.vue"; | |||
| import MyVideoItem from "./../../components/MyVideoItem.vue"; | |||
| // 工具 | |||
| import { | |||
| bytesToSize, | |||
| timestampToTime, | |||
| scrollToID, | |||
| formatSeconds, | |||
| } from "../../utils"; | |||
| // 接口 | |||
| import { | |||
| getVideoList, | |||
| doGetVideoDetialById, | |||
| doFindInviteCode, | |||
| deleteVideoById, | |||
| } from "../../api/myPage"; | |||
| Vue.use(Toast); | |||
| export default { | |||
| components: { | |||
| HeadTop, | |||
| MyVideoItem | |||
| }, | |||
| data() { | |||
| return { | |||
| showDialog: true,// 弹出层显示隐藏 | |||
| inPage: false, | |||
| isShowMessageCover: false, | |||
| videoList: [], | |||
| currentPage: 1, | |||
| pageSize: 4, | |||
| prePage: "", | |||
| total: "", | |||
| }; | |||
| }, | |||
| computed: { | |||
| ...mapState({ | |||
| characters: (state) => state.publicObj.characters, | |||
| }), | |||
| }, | |||
| methods: { | |||
| ...mapActions(["setCharacters"]), | |||
| go(url) { | |||
| this.$router.push(url); | |||
| }, | |||
| changeTime(timestamp, form) { | |||
| return timestampToTime(timestamp, form); | |||
| }, | |||
| pageChange() { | |||
| this.loadVideoList(this.currentPage, this.pageSize); | |||
| }, | |||
| // 点击空白区域退出提示 | |||
| exitCover(e) { | |||
| if (e.srcElement.id != "message") { | |||
| this.isShowMessageCover = false; | |||
| } | |||
| }, | |||
| // 秒转化时分秒 | |||
| formatSeconds(seconds) { | |||
| if (seconds) { | |||
| return formatSeconds(seconds); | |||
| } else { | |||
| return "无"; | |||
| } | |||
| }, | |||
| // 将bytes转化 | |||
| bytesToSize(bytes) { | |||
| if (bytes) { | |||
| return bytesToSize(bytes); | |||
| } else { | |||
| return "无"; | |||
| } | |||
| }, | |||
| // 查看详情 | |||
| goDetail(item) { | |||
| const status = item.videoStatus; | |||
| if (status == 0) { | |||
| this.$router.push({ | |||
| path: "/getPaper", | |||
| query: { | |||
| id: item.id, | |||
| }, | |||
| }); | |||
| } else if (status == 1) { | |||
| Toast.fail("视频生成中"); | |||
| return; | |||
| } else if (status == 2) { | |||
| const url = item.videoPathUri + item.videoPath; | |||
| this.$router.push({ | |||
| path: "/downloadVideo", | |||
| query: { | |||
| videoId: item.videoId, | |||
| videoUrl: url, | |||
| }, | |||
| }); | |||
| } else if (status == 3) { | |||
| this.$router.push({ | |||
| path: "/getPaper", | |||
| query: { | |||
| id: item.id, | |||
| }, | |||
| }); | |||
| } | |||
| }, | |||
| goDelete(id) { | |||
| Dialog.confirm({ | |||
| title: "删除作品", | |||
| message: "您确定要删除该作品吗?", | |||
| }) | |||
| .then(() => { | |||
| this.deleteVideoById(id); | |||
| this.loadVideoList(this.currentPage, this.pageSize); | |||
| }) | |||
| .catch(() => { | |||
| return; | |||
| }); | |||
| }, | |||
| /** | |||
| * @description:获取作品列表 | |||
| */ | |||
| async loadVideoList(pageNum, pageSize) { | |||
| try { | |||
| const res = await getVideoList(pageNum, pageSize); | |||
| console.log(res, "获取作品列表"); | |||
| this.videoList = res.data.list; | |||
| this.total = res.data.total; | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| } | |||
| }, | |||
| /** | |||
| * @description 通过视频id获取视频详情 | |||
| */ | |||
| async getVideoDetialById(id) { | |||
| try { | |||
| const res = await doGetVideoDetialById(id); | |||
| console.log(res, "通过视频id获取视频详情"); | |||
| return res.data; | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| } | |||
| }, | |||
| /** | |||
| * @description 根据id删除作品 | |||
| */ | |||
| async deleteVideoById(id) { | |||
| try { | |||
| const res = await deleteVideoById(id); | |||
| console.log(res, "根据id删除作品"); | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| } | |||
| }, | |||
| /** | |||
| * @description:查询用户邀请码状态 | |||
| */ | |||
| async checkInviteCode() { | |||
| try { | |||
| const res = await doFindInviteCode(); | |||
| console.log(res, "查询用户邀请码数据"); | |||
| const status = res.data.status; | |||
| // 当没有邀请码时 | |||
| if (status == 0) { | |||
| scrollToID("top"); | |||
| this.isShowMessageCover = true; | |||
| } else if (status == 1) { | |||
| this.goCreateNew(); | |||
| } | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| } | |||
| }, | |||
| goCreateNew() { | |||
| this.$router.push("/chooseModel"); | |||
| }, | |||
| }, | |||
| mounted() { | |||
| this.inPage = true; | |||
| scrollToID("top"); | |||
| }, | |||
| created() { | |||
| this.loadVideoList(1, this.pageSize); | |||
| }, | |||
| }; | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .page { | |||
| transform: translateX(30%); | |||
| opacity: 0; | |||
| transition: all 0.5s; // global-transition | |||
| padding-bottom: 25px; | |||
| &.active { | |||
| opacity: 1; | |||
| transform: translateX(0); | |||
| } | |||
| .logoBox { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| overflow: hidden; | |||
| cursor: pointer; | |||
| background-color: #606060; | |||
| .logo { | |||
| float: left; | |||
| width: 140px; | |||
| height: 40px; | |||
| } | |||
| .userInfo { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| color: #fff; | |||
| .userImg { | |||
| float: right; | |||
| width: 30px; | |||
| height: 30px; | |||
| margin-top: 3px; | |||
| margin-right: 10px; | |||
| margin-left: 15px; | |||
| } | |||
| } | |||
| } | |||
| .showIMG { | |||
| padding: 10px; | |||
| width: 100%; | |||
| height: 140px; | |||
| border-radius: 16px; | |||
| } | |||
| .item { | |||
| padding: 15px 10px; | |||
| .title { | |||
| font-size: 16px; | |||
| font-weight: 500; | |||
| // margin-left: 15px; | |||
| margin-bottom: 20px; | |||
| img { | |||
| margin-top: -5px; | |||
| vertical-align: middle; | |||
| width: 24px; | |||
| height: 18px; | |||
| background-size: 100% 100%; | |||
| } | |||
| } | |||
| ::v-deep .itemList { | |||
| .videoModel { | |||
| position: relative; | |||
| display: flex; | |||
| justify-content: space-between; | |||
| margin-bottom: 20px; | |||
| .videoPrv { | |||
| width: 150px; | |||
| height: 100px; | |||
| // background-color: #979797; | |||
| img { | |||
| position: absolute; | |||
| width: 150px; | |||
| height: 100px; | |||
| border-radius: 6px; | |||
| } | |||
| .cover { | |||
| position: absolute; | |||
| width: 150px; | |||
| height: 100px; | |||
| line-height: 100px; | |||
| background-color: #00000034; | |||
| text-align: center; | |||
| border-radius: 6px; | |||
| color: #fff; | |||
| } | |||
| } | |||
| .videoInfo { | |||
| flex: 1; | |||
| margin-left: 12px; | |||
| .videoName { | |||
| font-size: 16px; | |||
| font-weight: 600; | |||
| } | |||
| .createTime { | |||
| font-size: 11px; | |||
| color: #999999; | |||
| margin-top: 10px; | |||
| } | |||
| } | |||
| .showMore { | |||
| width: 20px; | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| // margin-left: 10px; | |||
| div { | |||
| width: 4px; | |||
| height: 4px; | |||
| background-color: #51D9CA; | |||
| } | |||
| } | |||
| .tag { | |||
| position: absolute; | |||
| right: 10px; | |||
| top: 10px; | |||
| padding: 1px 5px; | |||
| border-radius: 5px; | |||
| &.text { | |||
| color: #fff; | |||
| background-color: #a2a2a290; | |||
| } | |||
| &.generating { | |||
| background-color: #ffa600c2; | |||
| } | |||
| &.finish { | |||
| color: #ffffff; | |||
| background-color: #00ff88; | |||
| } | |||
| &.fail { | |||
| color: #ffffff; | |||
| background-color: #ff0000c3; | |||
| } | |||
| } | |||
| } | |||
| .noWork { | |||
| width: 100%; | |||
| height: 450px; | |||
| line-height: 450px; | |||
| font-size: 14px; | |||
| font-weight: 600; | |||
| text-align: center; | |||
| } | |||
| } | |||
| } | |||
| .goAdd { | |||
| position: sticky; | |||
| bottom: 25px; | |||
| left: 10px; | |||
| width: 300px; | |||
| height: 42px; | |||
| line-height: 42px; | |||
| font-size: 15px; | |||
| color: #fff; | |||
| text-align: center; | |||
| transform: translateX(-50%); | |||
| background-color: #0068b7; | |||
| border-radius: 5px; | |||
| box-shadow: #60606082 1px 1px 1px 1px; | |||
| margin-top: 25px; | |||
| margin-left: 190px; | |||
| } | |||
| .messageCover { | |||
| position: fixed; | |||
| top: 0; | |||
| width: 100%; | |||
| height: 100%; | |||
| background-color: #00000091; | |||
| transition: all 0.3s; | |||
| opacity: 0; | |||
| z-index: -1; | |||
| .message { | |||
| position: sticky; | |||
| top: 48%; | |||
| transform: translate(-50%, -50%); | |||
| width: 272px; | |||
| height: 290px; | |||
| border-radius: 5px; | |||
| background-color: #fff; | |||
| text-align: center; | |||
| transition: all 0.3s; | |||
| margin-left: 50%; | |||
| padding: 10px; | |||
| .connect { | |||
| font-size: 12px; | |||
| margin: 19px 0 10px 0; | |||
| } | |||
| .qrCode { | |||
| width: 203px; | |||
| height: 213px; | |||
| background-color: #ffffff; | |||
| border-radius: 5px; | |||
| border: solid 1px #595959; | |||
| margin: auto; | |||
| img { | |||
| width: 100%; | |||
| height: 100%; | |||
| } | |||
| } | |||
| .phoneNum { | |||
| float: left; | |||
| font-size: 11px; | |||
| margin-top: 8px; | |||
| margin-left: 34px; | |||
| } | |||
| .close { | |||
| position: absolute; | |||
| top: 8px; | |||
| right: 15px; | |||
| font-size: 18px; | |||
| color: #000; | |||
| } | |||
| .clickToClose { | |||
| position: absolute; | |||
| font-size: 14px; | |||
| color: #fff; | |||
| left: 50%; | |||
| bottom: -20%; | |||
| transform: translateX(-50%); | |||
| } | |||
| } | |||
| &.active { | |||
| z-index: 100; | |||
| opacity: 1; | |||
| } | |||
| } | |||
| .delete-button { | |||
| position: relative; | |||
| left: 1%; | |||
| height: 100%; | |||
| } | |||
| } | |||
| </style> | |||
| @@ -0,0 +1,520 @@ | |||
| <template> | |||
| <div :class="inPage ? 'page active' : 'page'"> | |||
| <div id="top"></div> | |||
| <HeadTop /> | |||
| <!-- 顶部图 --> | |||
| <img class="showIMG" src="../../assets/img/BG-Page.png" alt="" /> | |||
| <!-- 展示列表 --> | |||
| <div class="item"> | |||
| <div class="title"> | |||
| <img src="../../assets/img/myVideo.png" alt=""> | |||
| 我的视频作品 | |||
| </div> | |||
| <van-swipe-cell v-for="(item, index) in videoList"> | |||
| <div class="itemList"> | |||
| <div | |||
| v-if="videoList.length > 0" | |||
| class="videoModel" | |||
| :key="index" | |||
| @click="goDetail(item)" | |||
| > | |||
| <div class="videoPrv"> | |||
| <img src="../../assets/img/BG@2x.png" /> | |||
| <div v-if="item.videoStatus == 0" class="cover">草稿</div> | |||
| <div v-if="item.videoStatus == 1" class="cover">视频生成中</div> | |||
| <div v-if="item.videoStatus == 3" class="cover">视频生成失败</div> | |||
| <!-- <div v-if="item.videoStatus == ?" class="cover">排队中</div> --> | |||
| </div> | |||
| <div class="videoInfo"> | |||
| <div class="videoName"> | |||
| {{ item.title || "暂无" }} | |||
| </div> | |||
| <div class="createTime"> | |||
| 视频时长:{{ formatSeconds(item.videoTime) }} | |||
| </div> | |||
| <div class="createTime"> | |||
| 视频容量:{{ bytesToSize(item.videoSize) }} | |||
| </div> | |||
| <div class="createTime"> | |||
| 创建时间:{{ | |||
| changeTime(item.createDate, "YYYY-MM-DD hh:mm:ss") | |||
| }} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div v-if="videoList.length <= 0" class="noWork"> | |||
| 您还没有视频作品 | |||
| </div> | |||
| </div> | |||
| <template #right> | |||
| <van-button | |||
| square | |||
| text="删除" | |||
| type="danger" | |||
| class="delete-button" | |||
| @click="goDelete(item.id)" | |||
| /> | |||
| </template> | |||
| </van-swipe-cell> | |||
| </div> | |||
| <!-- 分页 --> | |||
| <van-pagination | |||
| v-model="currentPage" | |||
| :total-items="total" | |||
| :items-per-page="4" | |||
| @change="pageChange" | |||
| /> | |||
| <div class="goAdd" @click="checkInviteCode">+ 创作新作品</div> | |||
| <div | |||
| class="messageCover" | |||
| :class="isShowMessageCover ? 'active' : ''" | |||
| @click="exitCover" | |||
| > | |||
| <div class="message" id="message"> | |||
| <div class="connect" id="message">请添加微信与我们联系</div> | |||
| <div class="qrCode" id="message"> | |||
| <img src="../../assets/img/SuiMangQRCode.png" alt="" /> | |||
| </div> | |||
| <div class="phoneNum" id="message">或致电13260039498</div> | |||
| <div class="clickToClose">点击空白处关闭</div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| // 组件 | |||
| import Vue from "vue"; | |||
| import { Toast, Dialog } from "vant"; | |||
| import { mapState, mapActions } from "vuex"; | |||
| import HeadTop from "./../../components/common/head.vue"; | |||
| // 工具 | |||
| import { | |||
| bytesToSize, | |||
| timestampToTime, | |||
| scrollToID, | |||
| formatSeconds, | |||
| } from "../../utils"; | |||
| // 接口 | |||
| import { | |||
| getVideoList, | |||
| doGetVideoDetialById, | |||
| doFindInviteCode, | |||
| deleteVideoById, | |||
| } from "../../api/myPage"; | |||
| Vue.use(Toast); | |||
| export default { | |||
| components: { | |||
| HeadTop, | |||
| }, | |||
| data() { | |||
| return { | |||
| inPage: false, | |||
| isShowMessageCover: false, | |||
| videoList: [], | |||
| currentPage: 1, | |||
| pageSize: 4, | |||
| prePage: "", | |||
| total: "", | |||
| }; | |||
| }, | |||
| computed: { | |||
| ...mapState({ | |||
| characters: (state) => state.publicObj.characters, | |||
| }), | |||
| }, | |||
| methods: { | |||
| ...mapActions(["setCharacters"]), | |||
| go(url) { | |||
| this.$router.push(url); | |||
| }, | |||
| changeTime(timestamp, form) { | |||
| return timestampToTime(timestamp, form); | |||
| }, | |||
| pageChange() { | |||
| this.loadVideoList(this.currentPage, this.pageSize); | |||
| }, | |||
| // 点击空白区域退出提示 | |||
| exitCover(e) { | |||
| if (e.srcElement.id != "message") { | |||
| this.isShowMessageCover = false; | |||
| } | |||
| }, | |||
| // 秒转化时分秒 | |||
| formatSeconds(seconds) { | |||
| if (seconds) { | |||
| return formatSeconds(seconds); | |||
| } else { | |||
| return "无"; | |||
| } | |||
| }, | |||
| // 将bytes转化 | |||
| bytesToSize(bytes) { | |||
| if (bytes) { | |||
| return bytesToSize(bytes); | |||
| } else { | |||
| return "无"; | |||
| } | |||
| }, | |||
| // 查看详情 | |||
| goDetail(item) { | |||
| const status = item.videoStatus; | |||
| if (status == 0) { | |||
| this.$router.push({ | |||
| path: "/getPaper", | |||
| query: { | |||
| id: item.id, | |||
| }, | |||
| }); | |||
| } else if (status == 1) { | |||
| Toast.fail("视频生成中"); | |||
| return; | |||
| } else if (status == 2) { | |||
| const url = item.videoPathUri + item.videoPath; | |||
| this.$router.push({ | |||
| path: "/downloadVideo", | |||
| query: { | |||
| videoId: item.videoId, | |||
| videoUrl: url, | |||
| }, | |||
| }); | |||
| } else if (status == 3) { | |||
| this.$router.push({ | |||
| path: "/getPaper", | |||
| query: { | |||
| id: item.id, | |||
| }, | |||
| }); | |||
| } | |||
| }, | |||
| goDelete(id) { | |||
| Dialog.confirm({ | |||
| title: "删除作品", | |||
| message: "您确定要删除该作品吗?", | |||
| }) | |||
| .then(() => { | |||
| this.deleteVideoById(id); | |||
| this.loadVideoList(this.currentPage, this.pageSize); | |||
| }) | |||
| .catch(() => { | |||
| return; | |||
| }); | |||
| }, | |||
| /** | |||
| * @description:获取作品列表 | |||
| */ | |||
| async loadVideoList(pageNum, pageSize) { | |||
| try { | |||
| const res = await getVideoList(pageNum, pageSize); | |||
| console.log(res, "获取作品列表"); | |||
| this.videoList = res.data.list; | |||
| this.total = res.data.total; | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| } | |||
| }, | |||
| /** | |||
| * @description 通过视频id获取视频详情 | |||
| */ | |||
| async getVideoDetialById(id) { | |||
| try { | |||
| const res = await doGetVideoDetialById(id); | |||
| console.log(res, "通过视频id获取视频详情"); | |||
| return res.data; | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| } | |||
| }, | |||
| /** | |||
| * @description 根据id删除作品 | |||
| */ | |||
| async deleteVideoById(id) { | |||
| try { | |||
| const res = await deleteVideoById(id); | |||
| console.log(res, "根据id删除作品"); | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| } | |||
| }, | |||
| /** | |||
| * @description:查询用户邀请码状态 | |||
| */ | |||
| async checkInviteCode() { | |||
| try { | |||
| const res = await doFindInviteCode(); | |||
| console.log(res, "查询用户邀请码数据"); | |||
| const status = res.data.status; | |||
| // 当没有邀请码时 | |||
| if (status == 0) { | |||
| scrollToID("top"); | |||
| this.isShowMessageCover = true; | |||
| } else if (status == 1) { | |||
| this.goCreateNew(); | |||
| } | |||
| } catch (error) { | |||
| console.log(error, "error"); | |||
| Toast.fail(error.message); | |||
| } | |||
| }, | |||
| goCreateNew() { | |||
| this.$router.push("/chooseModel"); | |||
| }, | |||
| }, | |||
| mounted() { | |||
| this.inPage = true; | |||
| scrollToID("top"); | |||
| }, | |||
| created() { | |||
| this.loadVideoList(1, this.pageSize); | |||
| }, | |||
| }; | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .page { | |||
| transform: translateX(30%); | |||
| opacity: 0; | |||
| transition: all 0.5s; // global-transition | |||
| padding-bottom: 25px; | |||
| &.active { | |||
| opacity: 1; | |||
| transform: translateX(0); | |||
| } | |||
| .logoBox { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| overflow: hidden; | |||
| cursor: pointer; | |||
| background-color: #606060; | |||
| .logo { | |||
| float: left; | |||
| width: 140px; | |||
| height: 40px; | |||
| } | |||
| .userInfo { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| color: #fff; | |||
| .userImg { | |||
| float: right; | |||
| width: 30px; | |||
| height: 30px; | |||
| margin-top: 3px; | |||
| margin-right: 10px; | |||
| margin-left: 15px; | |||
| } | |||
| } | |||
| } | |||
| .showIMG { | |||
| padding: 10px; | |||
| width: 355px; | |||
| height: 130px; | |||
| border-radius: 16px; | |||
| } | |||
| .item { | |||
| padding-top: 15px; | |||
| padding-bottom: 15px; | |||
| padding-left: 10px; | |||
| padding-right: 10px; | |||
| .title { | |||
| font-size: 16px; | |||
| font-weight: 500; | |||
| // margin-left: 15px; | |||
| margin-bottom: 20px; | |||
| img { | |||
| margin-top: -5px; | |||
| vertical-align: middle; | |||
| width: 24px; | |||
| height: 18px; | |||
| background-size: 100% 100%; | |||
| } | |||
| } | |||
| .itemList { | |||
| .videoModel { | |||
| position: relative; | |||
| display: flex; | |||
| justify-content: space-between; | |||
| margin-bottom: 25px; | |||
| border-bottom: 1px solid #00000010; | |||
| padding: 0 20px 25px 25px; | |||
| .videoPrv { | |||
| width: 150px; | |||
| height: 100px; | |||
| // background-color: #979797; | |||
| img { | |||
| position: absolute; | |||
| width: 150px; | |||
| height: 100px; | |||
| } | |||
| .cover { | |||
| position: absolute; | |||
| width: 150px; | |||
| height: 100px; | |||
| line-height: 100px; | |||
| background-color: #00000034; | |||
| text-align: center; | |||
| color: #fff; | |||
| } | |||
| } | |||
| .videoInfo { | |||
| display: flex; | |||
| flex-direction: column; | |||
| justify-content: space-between; | |||
| margin-left: 10px; | |||
| .videoName { | |||
| font-size: 16px; | |||
| font-weight: 600; | |||
| } | |||
| .createTime { | |||
| font-size: 11px; | |||
| } | |||
| } | |||
| .tag { | |||
| position: absolute; | |||
| right: 10px; | |||
| top: 10px; | |||
| padding: 1px 5px; | |||
| border-radius: 5px; | |||
| &.text { | |||
| color: #fff; | |||
| background-color: #a2a2a290; | |||
| } | |||
| &.generating { | |||
| background-color: #ffa600c2; | |||
| } | |||
| &.finish { | |||
| color: #ffffff; | |||
| background-color: #00ff88; | |||
| } | |||
| &.fail { | |||
| color: #ffffff; | |||
| background-color: #ff0000c3; | |||
| } | |||
| } | |||
| } | |||
| .noWork { | |||
| width: 100%; | |||
| height: 450px; | |||
| line-height: 450px; | |||
| font-size: 14px; | |||
| font-weight: 600; | |||
| text-align: center; | |||
| } | |||
| } | |||
| } | |||
| .goAdd { | |||
| position: sticky; | |||
| bottom: 25px; | |||
| left: 10px; | |||
| width: 300px; | |||
| height: 42px; | |||
| line-height: 42px; | |||
| font-size: 15px; | |||
| color: #fff; | |||
| text-align: center; | |||
| transform: translateX(-50%); | |||
| background-color: #0068b7; | |||
| border-radius: 5px; | |||
| box-shadow: #60606082 1px 1px 1px 1px; | |||
| margin-top: 25px; | |||
| margin-left: 190px; | |||
| } | |||
| .messageCover { | |||
| position: fixed; | |||
| top: 0; | |||
| width: 100%; | |||
| height: 100%; | |||
| background-color: #00000091; | |||
| transition: all 0.3s; | |||
| opacity: 0; | |||
| z-index: -1; | |||
| .message { | |||
| position: sticky; | |||
| top: 48%; | |||
| transform: translate(-50%, -50%); | |||
| width: 272px; | |||
| height: 290px; | |||
| border-radius: 5px; | |||
| background-color: #fff; | |||
| text-align: center; | |||
| transition: all 0.3s; | |||
| margin-left: 50%; | |||
| padding: 10px; | |||
| .connect { | |||
| font-size: 12px; | |||
| margin: 19px 0 10px 0; | |||
| } | |||
| .qrCode { | |||
| width: 203px; | |||
| height: 213px; | |||
| background-color: #ffffff; | |||
| border-radius: 5px; | |||
| border: solid 1px #595959; | |||
| margin: auto; | |||
| img { | |||
| width: 100%; | |||
| height: 100%; | |||
| } | |||
| } | |||
| .phoneNum { | |||
| float: left; | |||
| font-size: 11px; | |||
| margin-top: 8px; | |||
| margin-left: 34px; | |||
| } | |||
| .close { | |||
| position: absolute; | |||
| top: 8px; | |||
| right: 15px; | |||
| font-size: 18px; | |||
| color: #000; | |||
| } | |||
| .clickToClose { | |||
| position: absolute; | |||
| font-size: 14px; | |||
| color: #fff; | |||
| left: 50%; | |||
| bottom: -20%; | |||
| transform: translateX(-50%); | |||
| } | |||
| } | |||
| &.active { | |||
| z-index: 100; | |||
| opacity: 1; | |||
| } | |||
| } | |||
| .delete-button { | |||
| position: relative; | |||
| left: 1%; | |||
| height: 100%; | |||
| } | |||
| } | |||
| </style> | |||
| @@ -2,25 +2,33 @@ | |||
| <div :class="inPage ? 'page active' : 'page'"> | |||
| <div id="top"></div> | |||
| <HeadTop /> | |||
| <!-- 顶部图 --> | |||
| <img class="showIMG" src="../../assets/img/BG-Page.png" alt="" /> | |||
| <!-- 展示列表 --> | |||
| <div class="item"> | |||
| <div class="title">我的视频作品</div> | |||
| <van-swipe-cell v-for="(item, index) in videoList"> | |||
| <div class="title"> | |||
| <img src="../../assets/img/myVideo.png" alt=""> | |||
| 我的视频作品 | |||
| <span class="floatRight" style="float: right;">草稿箱</span> | |||
| </div> | |||
| <!-- 具体内容 --> | |||
| <van-swipe-cell v-for="(item, index) in videoList" :key="item.id?item.id:index"> | |||
| <div class="itemList"> | |||
| <div | |||
| v-if="videoList.length > 0" | |||
| class="videoModel" | |||
| :key="index" | |||
| @click="goDetail(item)" | |||
| > | |||
| <div class="videoPrv"> | |||
| > | |||
| <!-- 左侧图片 --> | |||
| <div class="videoPrv" @click="goDetail(item)"> | |||
| <img src="../../assets/img/BG@2x.png" /> | |||
| <div v-if="item.videoStatus == 0" class="cover">草稿</div> | |||
| <div v-if="item.videoStatus == 1" class="cover">视频生成中</div> | |||
| <div v-if="item.videoStatus == 3" class="cover">视频生成失败</div> | |||
| <!-- <div v-if="item.videoStatus == ?" class="cover">排队中</div> --> | |||
| </div> | |||
| <div class="videoInfo"> | |||
| <!-- 中间文字 --> | |||
| <div class="videoInfo" @click="goDetail(item)"> | |||
| <div class="videoName"> | |||
| {{ item.title || "暂无" }} | |||
| </div> | |||
| @@ -36,13 +44,25 @@ | |||
| }} | |||
| </div> | |||
| </div> | |||
| <!-- 右侧更多 --> | |||
| <div class="showMore" @click.stop="showDialog(item)"> | |||
| <div></div> | |||
| <div></div> | |||
| <div></div> | |||
| </div> | |||
| <!-- 弹出层 --> | |||
| <van-dialog class="dialog" | |||
| v-model="clickItem==item?showTrue:showFalse"> | |||
| <div @click="closeDialog"><i class="el-icon-edit" /> 编辑</div> | |||
| <div><i class="el-icon-delete" /> 删除</div> | |||
| </van-dialog> | |||
| </div> | |||
| <div v-if="videoList.length <= 0" class="noWork"> | |||
| 您还没有视频作品 | |||
| </div> | |||
| </div> | |||
| <template #right> | |||
| <!-- 右滑 --> | |||
| <!-- <template #right> | |||
| <van-button | |||
| square | |||
| text="删除" | |||
| @@ -50,17 +70,21 @@ | |||
| class="delete-button" | |||
| @click="goDelete(item.id)" | |||
| /> | |||
| </template> | |||
| </template> --> | |||
| </van-swipe-cell> | |||
| </div> | |||
| <!-- 分页 --> | |||
| <van-pagination | |||
| v-model="currentPage" | |||
| :total-items="total" | |||
| :items-per-page="4" | |||
| @change="pageChange" | |||
| /> | |||
| <div class="goAdd" @click="checkInviteCode">+ 创作新作品</div> | |||
| <!-- 创建新作品 --> | |||
| <!-- <div class="goAdd" @click="checkInviteCode">+ 创作新作品</div> --> | |||
| <div class="goNewAdd" @click="checkInviteCode"> | |||
| <i class="el-icon-plus"></i> | |||
| </div> | |||
| <div | |||
| class="messageCover" | |||
| @@ -84,7 +108,7 @@ | |||
| import Vue from "vue"; | |||
| import { Toast, Dialog } from "vant"; | |||
| import { mapState, mapActions } from "vuex"; | |||
| import HeadTop from "./../../components/common/head.vue"; | |||
| import HeadTop from "@/components/common/head.vue"; | |||
| // 工具 | |||
| import { | |||
| bytesToSize, | |||
| @@ -107,6 +131,9 @@ export default { | |||
| }, | |||
| data() { | |||
| return { | |||
| clickItem: -1,// 弹出层显示隐藏 | |||
| showTrue: true,// 弹出层显示隐藏 | |||
| showFalse: false,// 弹出层显示隐藏 | |||
| inPage: false, | |||
| isShowMessageCover: false, | |||
| videoList: [], | |||
| @@ -124,7 +151,13 @@ export default { | |||
| methods: { | |||
| ...mapActions(["setCharacters"]), | |||
| closeDialog() { | |||
| Dialog.close | |||
| }, | |||
| // 点击显示编辑删除 | |||
| showDialog(item) { | |||
| this.clickItem=item | |||
| }, | |||
| go(url) { | |||
| this.$router.push(url); | |||
| }, | |||
| @@ -326,26 +359,33 @@ export default { | |||
| } | |||
| } | |||
| .showIMG { | |||
| padding: 10px; | |||
| width: 100%; | |||
| height: 130px; | |||
| height: 140px; | |||
| border-radius: 16px; | |||
| } | |||
| .item { | |||
| padding-top: 15px; | |||
| padding-bottom: 15px; | |||
| padding: 15px 10px; | |||
| .title { | |||
| font-size: 15px; | |||
| font-weight: 600; | |||
| margin-left: 15px; | |||
| font-size: 16px; | |||
| font-weight: 500; | |||
| // margin-left: 15px; | |||
| margin-bottom: 20px; | |||
| img { | |||
| margin-top: -5px; | |||
| vertical-align: middle; | |||
| width: 24px; | |||
| height: 18px; | |||
| background-size: 100% 100%; | |||
| } | |||
| } | |||
| .itemList { | |||
| .videoModel { | |||
| position: relative; | |||
| display: flex; | |||
| justify-content: space-between; | |||
| margin-bottom: 25px; | |||
| border-bottom: 1px solid #00000010; | |||
| padding: 0 20px 25px 25px; | |||
| margin-bottom: 20px; | |||
| .videoPrv { | |||
| width: 150px; | |||
| height: 100px; | |||
| @@ -354,6 +394,7 @@ export default { | |||
| position: absolute; | |||
| width: 150px; | |||
| height: 100px; | |||
| border-radius: 6px; | |||
| } | |||
| .cover { | |||
| position: absolute; | |||
| @@ -362,22 +403,62 @@ export default { | |||
| line-height: 100px; | |||
| background-color: #00000034; | |||
| text-align: center; | |||
| border-radius: 6px; | |||
| color: #fff; | |||
| } | |||
| } | |||
| .videoInfo { | |||
| display: flex; | |||
| flex-direction: column; | |||
| justify-content: space-between; | |||
| margin-left: 10px; | |||
| flex: 1; | |||
| margin-left: 12px; | |||
| .videoName { | |||
| font-size: 16px; | |||
| font-weight: 600; | |||
| } | |||
| .createTime { | |||
| font-size: 11px; | |||
| color: #999999; | |||
| margin-top: 10px; | |||
| } | |||
| } | |||
| .showMore { | |||
| width: 20px; | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| // margin-left: 10px; | |||
| div { | |||
| width: 4px; | |||
| height: 4px; | |||
| background-color: #51D9CA; | |||
| } | |||
| } | |||
| .dialog { | |||
| i { | |||
| margin-left: -10px; | |||
| } | |||
| } | |||
| // 弹出层样式 | |||
| ::v-deep .van-dialog { | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| top: 70%; | |||
| left: 290px; | |||
| padding-left: 10px; | |||
| width: 80px; | |||
| height: 60px; | |||
| border-radius: 12px; | |||
| font-size: 14px; | |||
| line-height: 28px; | |||
| text-align: center; | |||
| box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1); | |||
| } | |||
| ::v-deep .van-overlay { | |||
| background-color: rgba(0,0,0,0); | |||
| } | |||
| ::v-deep .van-button { | |||
| display: none; | |||
| } | |||
| .tag { | |||
| position: absolute; | |||
| right: 10px; | |||
| @@ -428,6 +509,20 @@ export default { | |||
| margin-top: 25px; | |||
| margin-left: 190px; | |||
| } | |||
| .goNewAdd { | |||
| position: sticky; | |||
| left: 300px; | |||
| bottom: 25px; | |||
| width: 60px; | |||
| height: 60px; | |||
| border-radius: 50%; | |||
| font-size: 40px; | |||
| line-height: 60px; | |||
| text-align: center; | |||
| color: #ffffff; | |||
| background: linear-gradient(316deg, #6EE4D7 0%, #37C4F1 32%, #A49AFC 100%); | |||
| box-shadow: 0px 2px 6px 0px rgba(114,100,245,0.25); | |||
| } | |||
| .messageCover { | |||
| position: fixed; | |||
| top: 0; | |||