beelink/src/views/mine/Archives.vue

1020 lines
39 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="archives">
<div class="user-info">
<div class="avatar">
<a-upload
v-model:fileList="fileList"
name="avatar"
list-type="picture-card"
class="avatar-uploader"
:show-upload-list="false"
:customRequest="uploadspic"
@change="handleChange"
>
<a-avatar :size="85" shape="circle" :src="userinfo.img">
<template v-slot:icon><UserOutlined /></template>
</a-avatar>
<div class="mengceng" style="width: 85px;height: 85px;">
修改头像
</div>
</a-upload>
<div class="user-name" v-if="showname">
<div class="update-btn" @click="updateUserName" style="color: #fff;cursor: unset;">修改</div>
<div class="value">{{ userinfo.name }}</div>
<div class="update-btn" @click="updateUserName">修改</div>
</div>
<div class="user-name" v-else>
<a-input size="small" v-model:value="userinfo.name" placeholder="请输入新的昵称" />
</div>
</div>
<div class="form-box basic">
<div class="title">基本信息</div>
<div class="main-container">
<div class="input-box country">
<div class="label">来自国家</div>
<a-select
v-model:value="userinfo.country"
style="width: 171px"
size="small"
ref="select"
:getPopupContainer="triggerNode => triggerNode.parentNode"
>
<a-select-option v-for="(item, index) in chiveslist[0]" :key="index" :value="item.name">
{{ item.name }}
</a-select-option>
</a-select>
</div>
<div class="input-box address">
<div class="label">居住地</div>
<a-input size="small" v-model:value="userinfo.live" placeholder="请输入居住地" />
</div>
<div class="input-box teach-lang">
<div class="label">教授</div>
<a-select
v-model:value="userinfo.tlanguageValue"
style="width: 171px"
size="small"
ref="select"
:getPopupContainer="triggerNode => triggerNode.parentNode"
>
<a-select-option v-for="(item, index) in chiveslist[1]" :key="index" :value="item.languageid">
{{ item.name }}
</a-select-option>
</a-select>
</div>
<div class="input-box speak-lang">
<div class="label">我还会说</div>
<div class="speak-array">
<div class="lang-items">
<div class="speak-item" v-for="(lang, indexs) in userinfo.willsay" :key="indexs">
<a-select
v-model:value="lang.name"
style="width: 171px"
size="small"
ref="select"
@change="choosewillsay"
:getPopupContainer="triggerNode => triggerNode.parentNode"
>
<a-select-option v-for="(item, index) in chiveslist[1]" :key="index" :value="item.languageid" >
{{ item.name }} {{item.languageid}}
</a-select-option>
</a-select>
<div class="proficiency">
<div class="p-title">熟练度</div>
<div class="value">
<!-- <a-rate v-model:value="lang.proficiency" style="fontSize: 15px">
<template v-slot:character><img src="" style="width: 10px;height: 10px;background-color: #0f0;"/>{{}}</template>
</a-rate> -->
<img @click="setlevel(indexs, i)" v-for="i in 5" :key="i" :src="lang.level >= i ? smilet : smile" alt="" />
</div>
</div>
</div>
</div>
<div class="update-btn" @click="addSpeakLang">继续添加</div>
</div>
</div>
<div class="input-box native-lang">
<div class="label">母语</div>
<!-- <a-select
v-model:value="userinfo.mtongue"
style="width: 171px"
size="small"
ref="select"
:getPopupContainer="triggerNode => triggerNode.parentNode"
>
<a-select-option v-for="(item, index) in chiveslist[1]" :key="index" :value="item.name">
{{ item.name }}
</a-select-option>
</a-select> -->
<a-input size="small" v-model:value="userinfo.mtongue" placeholder="请输入新的母语" />
</div>
<div class="input-box video-lang">
<div class="label">短视频</div>
<a-upload
list-type="picture"
:customRequest="uploads"
:beforeUpload="beforeVideoUpload"
>
<div class="upload-image">
<PlaySquareOutlined
style="fontsize: 22px"
v-if="uploadprogress == 0"
/>
<a-progress
type="circle"
:percent="uploadprogress"
:width="80"
v-else
/>
</div>
</a-upload>
<div class="demand">
<p class="one-line-hide">视频要求</p>
<p class="one-line-hide"> 1.上传视频时间要求为30s之内</p>
<p class="one-line-hide">2.支持文件大小100M</p>
<p class="one-line-hide">3.文件扩展名fivmp4文件扩展名fivmp4</p>
</div>
</div>
<div class="input-box introduce">
<div class="label">自我介绍</div>
<a-textarea v-model:value="userinfo.desc" class="introduce-textarea" />
</div>
</div>
</div>
<div class="form-box contact">
<div class="title">联系方式</div>
<div class="main-container">
<div class="input-box mailbox">
<div class="label">邮箱</div>
<a-input size="small" v-model:value="userinfo.email" placeholder="请输入邮箱" />
</div>
<div class="input-box phone-box">
<div class="label">手机号</div>
<div class="phone">{{ userinfo.mobile }}</div>
<div class="update-btn" @click="togglePhoneModal(true)">更换手机号</div>
</div>
</div>
</div>
<div class="form-box system-setting">
<div class="title">系统设置</div>
<div class="main-container">
<div class="input-box password-box">
<div class="label">密码</div>
<div class="password">************</div>
<div class="update-btn" @click="togglePasswordModal(true)">修改密码</div>
</div>
<div class="input-box time-zone-box">
<div class="label">时区</div>
<a-select
v-model:value="userinfo.zoneid"
style="width: 171px"
size="small"
ref="select"
:getPopupContainer="triggerNode => triggerNode.parentNode"
>
<a-select-option v-for="(item, index) in zonelist" :key="index" :value="item.zoneid">
{{item.city}}{{item.gmt}}
</a-select-option>
</a-select>
</div>
<div class="input-box currency-box">
<div class="label">货币</div>
<a-select
style="width: 171px"
size="small"
ref="select"
:getPopupContainer="triggerNode => triggerNode.parentNode"
@change="currencychange"
v-model:value="currencyindex"
>
<a-select-option v-for="(item, index) in currencylist" :key="index" :value="item.value">
{{item.name}}
</a-select-option>
</a-select>
</div>
<div class="input-box time-zone">
<div class="label">语言</div>
<a-select
v-model:value="userinfo.languageValue"
style="width: 171px"
size="small"
ref="select"
:getPopupContainer="triggerNode => triggerNode.parentNode"
>
<a-select-option v-for="(item, index) in languages" :key="index" :value="item.value">
{{ item.name }}
</a-select-option>
</a-select>
</div>
</div>
</div>
<div class="modal-container">
<a-modal
centered
:footer="null"
:getContainer="modalNode"
dialogClass="modal-dialog"
v-model:visible="updatePhoneVisible"
@cancel="hidePhoneModal"
>
<template v-slot:closeIcon>
<img src="@/static/images/delete.png" class="close" />
</template>
<!-- 换绑手机号第一步 -->
<div class="public-class phone-container" v-if="!isSecondStep">
<div class="title">请完成以下认证</div>
<div class="title sub-title">请输入{{ userinfo.mobile }}收到的验证短信码</div>
<div class="form-box">
<div class="form-item">
<label class="label">手机验证码</label>
<a-input size="small" v-model:value="verificationCode" />
<div @click="sendVerificationCode(userinfo.code+userinfo.mobile)" class="confirm-btn">获取验证码<span v-if="remainTime>0">{{ remainTime }}s</span></div>
</div>
</div>
<div @click="nextPhoneStep" class="confirm-btn">下一步</div>
</div>
<!-- 换绑手机号第二步 -->
<div class="public-class phone-container second-step" v-else>
<div class="title">完成以下操作绑定新号码</div>
<div class="form-box">
<div class="form-item">
<label class="label">手机号</label>
<!-- <a-input size="small" v-model:value="bindPhone.number" /> -->
<a-input-group compact class="telbox">
<a-select :default-value="quhaolist[0].code" size="small" @change="getquhao">
<a-select-option v-for="(i,j) in quhaolist" :key="j" :value="i.code">
{{i.name}}+{{i.code}}
</a-select-option>
<!-- <a-select-option value="Jiangsu"> Jiangsu </a-select-option> -->
</a-select>
<div class="line"></div>
<a-input v-model:value="mynewtel" size="small" placeholder="请输入您的手机号" />
</a-input-group>
</div>
<div class="form-item">
<label class="label">手机验证码</label>
<a-input size="small" v-model:value="bindPhone.code" />
<div @click="sendVerificationCode(myquhao+mynewtel)" class="confirm-btn">获取验证码<span v-if="remainTime>0">{{ remainTime }}s</span></div>
</div>
</div>
<div @click="updatePhoneNumber" class="confirm-btn">绑定手机</div>
</div>
</a-modal>
<!-- 修改密码 -->
<a-modal
centered
:footer="null"
:getContainer="modalNode"
dialogClass="modal-dialog"
v-model:visible="updatePasswordVisible"
@cancel="hidePasswordModal"
>
<template v-slot:closeIcon>
<img src="@/static/images/delete.png" class="close" />
</template>
<div class="public-class password-container">
<div class="title">完成以下操作修改账号密码</div>
<div class="form-box">
<div class="form-item">
<label class="label">原密码</label>
<a-input-password size="small" :visibilityToggle="false" v-model:value="passwordForm.original" />
</div>
<div class="form-item">
<label class="label">新密码</label>
<a-input-password size="small" :visibilityToggle="false" v-model:value="passwordForm.password" />
</div>
<div class="form-item">
<label class="label">确认新密码</label>
<a-input-password size="small" :visibilityToggle="false" v-model:value="passwordForm.topassword" />
</div>
</div>
<div @click="updateUserPassword" class="confirm-btn">修改密码</div>
</div>
</a-modal>
</div>
<div class="submit-btn" @click="submitInfo">保存信息</div>
</div>
<nav-bottom></nav-bottom>
</div>
</template>
<script lang="ts">
import { computed, defineComponent, onMounted, reactive, Ref, ref, toRaw, watch } from "vue";
import { UserOutlined, PlaySquareOutlined } from '@ant-design/icons-vue';
import NavBottom from '@/components/NavBottom.vue';
import { uploadflie } from "@/utils/vod"
import store from '@/store';
import smile from "@/static/images/smile.png"
import smilet from "@/static/images/smilet.png"
import { changetel, checksmscode, editpassword, getarchives, getcurrencys, getlanguages, getquhaolist, getzonelist, putmember, sendsms } from "@/api/index"
import { message } from 'ant-design-vue';
export default defineComponent({
name: "Archives",
components: {
UserOutlined,
PlaySquareOutlined,
NavBottom
},
setup(){
interface SpeakItem{
lang: string;
proficiency: number;
}
const otherSpeak: Array<SpeakItem> = [{
lang: '请选择',
proficiency: 0,
}];
const userinfo = computed(() => {return store.state.userinfo})
// 表单数据
const currencyindex=ref<string>(userinfo.value.currencyValue)
const formData = ref(toRaw(userinfo.value));
watch(userinfo,() => {
formData.value = toRaw(userinfo.value);
console.log(userinfo.value.currencyValue,"listsssss")
currencyindex.value=userinfo.value.currencyValue
console.log(currencyindex.value,"listsssss")
})
const modalNode = () => document.getElementsByClassName('modal-container')[0]
const chiveslist = ref<any>([[],[]]);
const languages = ref<unknown>([]);
const quhaolist = ref<any>([]);
const myquhao = ref<string>("");
const mynewtel = ref<string>("");
const isSecondStep: Ref<boolean> = ref(false);
const currencylist=ref<any>([{
alias: "CNY",
code: "104110041000",
createdAt: "2020-08-19 11:54:59",
deletedAt: null,
dictionaryid: 241,
name: "人民币¥",
position: 1,
publish: 1,
updatedAt: "2020-08-19 11:54:59",
value: "1"
}])
const zonelist=ref<any>([{
city: "中途岛",
gmt: "GMT-11:00",
id: "Pacific/Midway",
zoneid: 1
}])
onMounted(async ()=>{
chiveslist.value = await getarchives()
languages.value = await getlanguages()
quhaolist.value = await getquhaolist()
myquhao.value = quhaolist.value[0].code
currencylist.value = await getcurrencys()
zonelist.value=await getzonelist()
// currencyindex.value=userinfo.value.currencyValue
console.log(userinfo.value)
})
/**
* 修改用户名
* @return { void }
*/
const showname = ref(true)
function updateUserName (): void {
console.log('修改');
showname.value = false
}
/**
* 添加我还会说语言
* @return { void }
*/
function addSpeakLang (): void {
formData.value.willsay.push({
name: '请选择',
level: 0
});
formData.value.willsayValue.push({
name: "",
level: 0
});
}
// 验证码
const verificationCode: Ref<string> = ref(''),
updatePhoneVisible: Ref<boolean> = ref(false);
/**
* 关闭手机对话框 清空数据
*/
function hidePhoneModal(): void {
verificationCode.value = '';
isSecondStep.value=false
console.log("close")
}
/**
* 显示修改手机号对话框
*/
function togglePhoneModal(value: boolean): void {
updatePhoneVisible.value = value;
if(!value) {
hidePhoneModal();
}
}
// 获取验证码间隔
const remainTime: Ref<number> = ref(0);
/**
* 计算验证码倒计时
*/
function computedVerificationCode(): void {
remainTime.value = 60;
const timer = setInterval(() => {
if(remainTime.value > 0) {
remainTime.value --;
} else {
clearInterval(timer);
}
}, 1000)
}
/**
* 发送验证码
*/
function sendVerificationCode(tel: string): void {
if(remainTime.value === 0) {
computedVerificationCode();
console.log(tel,"send")
sendsms(tel, 0)
}
}
// 绑定手机号是否是第二步
interface BindPhoneItem{
number: string | number;
code: string | number;
}
const bindPhone: BindPhoneItem = reactive({
number: '',
code: '',
});
/**
* 绑定手机号下一步
*/
async function nextPhoneStep(): Promise<void> {
remainTime.value = 0
if(!isSecondStep.value){
console.log(formData.value.code)
if(verificationCode.value == ""){
return ;
}
const res=await checksmscode(formData.value.code+formData.value.mobile,verificationCode.value)
console.log(res,"0.0")
if(res){
isSecondStep.value = true;
}
// isSecondStep.value = true;
}
// isSecondStep.value = true;
}
/**
* 修改手机号
* @return { void }
*/
async function updatePhoneNumber (): Promise<void> {
console.log('修改手机号');
console.log(mynewtel.value,myquhao.value,bindPhone.code)
const res=await checksmscode(myquhao.value+mynewtel.value,bindPhone.code.toString())
console.log(res,"xiugai")
if(res){
const res1=await changetel(mynewtel.value)
if(res1){
store.dispatch("setUserInfo");
updatePhoneVisible.value=false
}
}
}
function getquhao(e?: any){
console.log(e)
myquhao.value=e.toString()
}
// 是否显示修改密码框
const updatePasswordVisible: Ref<boolean> = ref(false);
interface PassWord {
original?: string;
password?: string;
topassword?: string;
}
const passwordForm: PassWord = reactive({
original: '',
password: '',
topassword: '',
})
/**
* 密码对话框清空数据
*/
function hidePasswordModal(): void {
passwordForm.original = '';
passwordForm.password = '';
passwordForm.topassword = '';
}
/**
* 显示修改密码对话框
*/
function togglePasswordModal(value: boolean): void {
updatePasswordVisible.value = value;
if(!value) {
hidePasswordModal();
}
}
/**
* 修改密码
* @return { void }
*/
function updateUserPassword(): void {
console.log(toRaw(passwordForm))
if(toRaw(passwordForm).password === toRaw(passwordForm).topassword) {
if(toRaw(passwordForm).original != '') {
// console.log(toRaw(passwordForm).password);
editpassword(toRaw(passwordForm))
togglePasswordModal(false);
}else{
message.error("原密码不能为空")
}
}else{
message.error("两次密码输入不一致")
}
}
/**
* 提交表单
* @return { void }
*/
async function submitInfo (): Promise<void> {
// for(let i in toRaw(formData.value).willsay){
// console.log(toRaw(formData.value).willsay[i])
// }
const uesrinfo = toRaw(formData.value)
for(let m=0;m<toRaw(chiveslist.value).length;m++){
for(const i in uesrinfo.willsayValue){
// console.log(toRaw(formData.value).willsayValue[i])
if(typeof uesrinfo.willsay[i].name=='string'){
// console.log(toRaw(chiveslist.value))
if(uesrinfo.willsay[i].name==toRaw(chiveslist.value)[m].name){
uesrinfo.willsayValue[i].name=toRaw(chiveslist.value)[m].languageid
}
}else{
uesrinfo.willsayValue[i].name=uesrinfo.willsay[i].name
}
uesrinfo.willsayValue[i].level=uesrinfo.willsay[i].level
}
}
console.log(uesrinfo)
// console.log(toRaw(formData.value));
if(userinfo.value.currency==''){
if(userinfo.value.currencyValue!=''){
for(let i=0;i<currencylist.value.length;i++){
if(userinfo.value.currencyValue==currencylist.value[i].name){
userinfo.value.currency=(i+1).toString()
}
}
}
}
putmember(uesrinfo)
}
// uploadflie()3.
function setlevel(index: number, level: number){
store.state.userinfo.willsay[index].level = level
}
/**
* 上传视频
*/
interface AntUpload{
action: string;
data: unknown;
file: File;
}
const uploadprogress: Ref<number> = ref(0);
async function uploads(file: AntUpload) {
uploadprogress.value=0
const res = await uploadflie(file.file, (info: any) => {
console.log(info);
uploadprogress.value = info.percent.toFixed(2) * 100;
});
userinfo.value.video = res.video.url;
}
if(formData.value.video != ""){
uploadprogress.value = 100
}
watch(formData,()=>{
if(formData.value.video != "" && uploadprogress.value == 0){
uploadprogress.value = 100
}
})
function choosewillsay(e?: any){
console.log(formData.value.willsayValue)
console.log(e)
}
function currencychange(e?: any){
console.log(e)
userinfo.value.currency=e
}
async function uploadspic(file: AntUpload) {
const res = await uploadflie(file.file, (info: any) => {
console.log(info);
// uploadpicprogress.value = info.percent.toFixed(2) * 100;
});
console.log(res);
// picinfo.fileId=res.fileId
// picinfo.url=res.video.url
formData.value.img = res.video.url;
}
currencyindex.value=userinfo.value.currencyValue
return {
modalNode,
formData,
updateUserName,
addSpeakLang,
verificationCode,
updatePhoneVisible,
hidePhoneModal,
sendVerificationCode,
remainTime,
isSecondStep,
nextPhoneStep,
bindPhone,
updatePhoneNumber,
togglePhoneModal,
updatePasswordVisible,
togglePasswordModal,
hidePasswordModal,
passwordForm,
updateUserPassword,
submitInfo,
userinfo: formData,
uploads,
smile,
smilet,
setlevel,
chiveslist,
languages,
uploadprogress,
choosewillsay,
mynewtel,
quhaolist,
getquhao,
myquhao,
currencylist,
zonelist,
currencychange,
currencyindex,
showname,
uploadspic
}
}
});
</script>
<style lang="scss" scoped>
.archives {
width: 100%;
min-width: 700px;
background-color: #ffffff;
padding: 46px;
border-radius: 17px;
position: relative;
.telbox{
margin-left:15px;
font-size: 12px;
}
.update-btn {
font-size: 11px;
color: #08AE98;
font-weight: 500;
cursor: pointer;
user-select: none;
}
.user-info {
margin-bottom: 42px;
.avatar {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin-bottom: 30px;
.user-name {
display: flex;
align-items: flex-end;
margin-top: 11px;
font-weight: bold;
.value {
font-size: 17px;
color: #111111;
margin: 0 10px;
line-height: 1;
}
}
}
.form-box {
margin-bottom: 20px;
.title {
font-size: 11px;
font-weight: bold;
color: #111111;
margin-bottom: 28px;
}
.main-container {
margin-left: 17px;
::v-deep(.input-box) {
display: flex;
align-items: center;
margin-bottom: 28px;
.label {
width: 60px;
font-size: 11px;
font-weight: 500;
color: #808080;
margin-right: 30px;
line-height: 23px;
align-self: flex-start;
}
.ant-input {
width: 171px;
padding: 6px 11px;
border-radius: 3px;
border: 1px solid #DCDFE0;
font-size: 11px;
color: #3F3F3F;
}
.ant-select {
font-size: 12px;
color: #3F3F3F;
}
.ant-select-dropdown {
.ant-select-dropdown-menu-item {
font-size: 12px;
}
}
}
.speak-lang {
.speak-array {
display: flex;
.lang-items {
.speak-item {
display: flex;
align-items: center;
&:not(:last-child) {
margin-bottom: 28px;
}
.proficiency {
margin: 0 107px 0 17px;
display: flex;
align-items: center;
.p-title {
font-size: 11px;
font-weight: 500;
color: #808080;
margin-right: 14px;
}
.value{
display: flex;
>img{
width: 15px;
height: 15px;
margin-right: 6px;
}
}
}
}
}
.update-btn {
align-self: flex-end;
}
}
}
.video-lang {
.upload-image {
width: 171px;
height: 96px;
border: 1px solid #DCDFE0;
border-radius: 3px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 17px;
}
.demand {
line-height: 17px;
font-size: 10px;
font-weight: 500;
color: #808080;
width: 134px;
p {
margin: 0;
}
}
}
.introduce {
.ant-input {
width: 359px;
}
.introduce-textarea {
height: 85px;
min-height: 85px;
max-height: 85px;
}
}
.phone-box {
.phone {
font-size: 11px;
font-weight: bold;
color: #404040;
margin-right: 112px;
}
}
.password-box {
.password {
margin-right: 123px;
}
}
}
}
::v-deep(.modal-dialog) {
.close {
width: 14px;
height: 14px;
}
.ant-modal-content {
box-sizing: border-box;
padding: 25px 30px;
width: 569px;
background: #FFFFFF;
box-shadow: 0px 4px 6px 0px rgba(102, 102, 102, 0.07);
border-radius: 28px;
.public-class {
.title {
font-size: 11px;
font-weight: bold;
color: #111111;
}
.form-box {
.form-item {
display: flex;
align-items: center;
.label {
font-size: 11px;
font-weight: 500;
color: #7F7F7F;
}
}
}
.confirm-btn {
display: inline-block;
background: #07AD97;
border-radius: 2px;
font-size: 9px;
font-weight: 500;
color: #FFFFFF;
text-align: center;
cursor: pointer;
user-select: none;
height: 22px;
line-height: 22px;
padding: 0 17px;
}
}
.password-container {
.title {
margin-bottom: 30px;
}
.form-box {
margin-bottom: 50px;
.form-item {
.label {
width: 90px;
margin-right: 10px;
}
&:not(:last-child) {
margin-bottom: 28px;
}
.ant-input-password {
width: 170px;
font-size: 11px;
color: #3F3F3F;
// .ant-input {
// letter-spacing: 0;
// }
}
}
}
}
.phone-container {
.sub-title {
margin: 16px 0 40px;
}
.form-box {
margin-bottom: 50px;
.form-item {
.label {
width: 80px;
margin-right: 10px;
}
.ant-input {
width: 170px;
font-size: 11px;
color: #3F3F3F;
margin-right: 28px;
}
}
}
}
.second-step {
.title {
margin-bottom: 33px;
}
.form-box {
.form-item {
&:not(:last-child) {
margin-bottom: 28px;
}
}
}
}
}
}
.submit-btn {
width: 63px;
height: 23px;
background: #08AE98;
border-radius: 3px;
font-size: 10px;
font-weight: 500;
color: #FFFFFF;
text-align: center;
line-height: 23px;
cursor: pointer;
user-select: none;
}
}
::v-deep(.ant-upload-list) {
display: none;
}
.avatar-uploader{
width: unset;
padding: 0;
border: none;
background-color: none;
position: relative;
&::v-deep(.ant-upload){
padding: 0;
border: none;
background-color: #fff;
width: unset;
height: unset;
}
.mengceng{
position: absolute;
left: 0;
top: 0;
opacity:0;
font-size: 10px;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
background-color: #000;
border-radius: 50%;
line-height: 1;
&:hover{
opacity: 0.5;
}
}
}
}
</style>