diff --git a/api/public.js b/api/public.js
index 9d780a2..795d170 100644
--- a/api/public.js
+++ b/api/public.js
@@ -1,13 +1,14 @@
import { get } from "@/utils/storeInfo";
import require from "@/utils/require";
import { Toast } from "antd-mobile";
+import { JSEncrypt } from "jsencrypt";
//关注和取关功能
export const handleLogout = async () => {
const account = get("account");
try {
const data = await require("POST", `/api/login/logout`, {
body: {
- mid:account.mid
+ mid: account.mid,
},
});
if (data.ret === -1) {
@@ -55,19 +56,22 @@ export const handleFollow = async (isFollowed, followedID, callback) => {
};
//点赞和取消点赞功能
-export const thumbsUp = async (id, times, callback,isZone) => {
-
+export const thumbsUp = async (id, times, callback, isZone) => {
try {
- const body = isZone?{
- zone_moment_id: id,
- times: times == 1 ? -1 : 1,
- }:{
- moment_id: id,
- times: times == 1 ? -1 : 1,
- };
+ const body = isZone
+ ? {
+ zone_moment_id: id,
+ times: times == 1 ? -1 : 1,
+ }
+ : {
+ moment_id: id,
+ times: times == 1 ? -1 : 1,
+ };
console.log("body", body);
- const data = await require("POST", `/api/${isZone?"zone_moment":"moment"}/thumbs_up`, {
+ const data = await require("POST", `/api/${
+ isZone ? "zone_moment" : "moment"
+ }/thumbs_up`, {
body,
});
if (data.ret === -1) {
@@ -136,8 +140,7 @@ export async function checkRelation(subMid, objMid, predicate) {
// 获取用户信息
export async function getUserInfo() {
try {
- const data =
- await require("POST", `/api/account/list_by_mid`, null, true);
+ const data = await require("POST", `/api/account/list_by_mid`, null, true);
if (data.ret === -1) {
Toast.show({
icon: "fail",
@@ -230,4 +233,33 @@ export const createOrder = async (type = "alipay_h5") => {
} finally {
setIsLoading(false);
}
-};
\ No newline at end of file
+};
+
+//点击获取验证码
+export const handleVerification = async (mobilePhone="",regionCode) => {
+ console.log("mobilePhone",mobilePhone.toString())
+ //手机号校验
+ if (!mobilePhone.toString().match(/^1[3456789]\d{9}$/)) {
+ Toast.show({
+ icon: "fail",
+ content: "手机号码格式错误",
+ position: "top",
+ });
+ return;
+ }
+ //对手机号进行RSA加密
+ const encrypt = new JSEncrypt();
+ encrypt.setPublicKey(process.env.EXPO_PUBLIC_RSA_KEY);
+ const mobile_phone = encrypt.encrypt(mobilePhone);
+ //发送短信验证码
+ try {
+ await require("POST", `/api/veri_code/send`, {
+ body: {
+ mobile_phone: mobile_phone,
+ region_code: regionCode,
+ },
+ });
+ } catch (error) {
+ console.error(error);
+ }
+};
diff --git a/app/my/setting/editPassword/page.js b/app/my/setting/editPassword/page.js
index 15f092c..580210d 100644
--- a/app/my/setting/editPassword/page.js
+++ b/app/my/setting/editPassword/page.js
@@ -1,13 +1,19 @@
"use client";
-import React, { useState } from "react";
+import React, { useState, useEffect } from "react";
import { Button, Input, Divider } from "antd-mobile";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleLeft } from "@fortawesome/free-solid-svg-icons";
import { useRouter } from "next/navigation";
+import { get } from "@/utils/storeInfo";
import UploadImgs from "@/components/UploadImgs";
+import { handleVerification } from "@/api/public";
+import { JSEncrypt } from "jsencrypt";
+import { cryptoPassword } from "@/utils/crypto";
+import require from "@/utils/require";
+import { signOut } from "@/utils/auth";
export default function EditPassword() {
- const [regionCode, setRegionCode] = useState("");
+ const [regionCode, setRegionCode] = useState("86");
const [mobilePhone, setMobilePhone] = useState("");
const [veriCode, setVeriCode] = useState("");
const [newPassword, setNewPassword] = useState("");
@@ -15,6 +21,125 @@ export default function EditPassword() {
const [isCounting, setIsCounting] = useState(false);
const [seconds, setSeconds] = useState(60);
const router = useRouter();
+ // useEffect(() => {
+ // const mobile_phone = get("mobile_phone");
+ // console.log("mobile_phone",mobile_phone)
+ // setMobilePhone(mobile_phone);
+ // }, []);
+ //获取之前缓存的用户的手机号
+ useEffect(() => {
+ const mobile_phone = get("mobile_phone");
+ const region_code = get("region_code");
+ if (mobile_phone && region_code) {
+ setMobilePhone(mobile_phone);
+ setRegionCode(region_code);
+ }
+ }, []);
+ useEffect(() => {
+ let interval;
+ if (isCounting && seconds > 0) {
+ interval = setInterval(() => {
+ setSeconds(seconds - 1);
+ }, 1000);
+ } else {
+ setIsCounting(false);
+ setSeconds(60);
+ clearInterval(interval);
+ }
+ return () => {
+ clearInterval(interval);
+ };
+ }, [isCounting, seconds]);
+ const getVerification = async () => {
+ //开始倒计时
+ setIsCounting(true);
+ handleVerification(mobilePhone, regionCode);
+ };
+ //点击修改密码
+ const handleUpdatePassword = async () => {
+ //验证数据格式
+ if (!mobilePhone.match(/^1[3456789]\d{9}$/)) {
+ Toast.show({
+ icon: "fail",
+ content: "手机号码格式错误",
+ position: "top",
+ });
+ return;
+ }
+ if (!veriCode) {
+ Toast.show({
+ icon: "fail",
+ content: "请输入验证码",
+ position: "top",
+ });
+ return;
+ }
+ if (!confirmPassword) {
+ Toast.show({
+ icon: "fail",
+ content: "请再次输入您的密码",
+ position: "top",
+ });
+ return;
+ }
+ if (newPassword != confirmPassword) {
+ Toast.show({
+ icon: "fail",
+ content: "两次输入密码不一致",
+ position: "top",
+ });
+ return;
+ }
+ if (newPassword.length < 8) {
+ Toast.show({
+ icon: "fail",
+ content: "新密码不得小于8位",
+ position: "top",
+ });
+ return;
+ }
+ if (newPassword.length > 15) {
+ Toast.show({
+ icon: "fail",
+ content: "新密码不得大于15位",
+ position: "top",
+ });
+ return;
+ }
+ //对手机号进行RSA加密
+ const encrypt = new JSEncrypt();
+ encrypt.setPublicKey(process.env.NEXT_PUBLIC_RSA_KEY);
+ const mobile_phone = encrypt.encrypt(mobilePhone);
+ //MD5加密新旧密码
+ const encryptedNewPassword = cryptoPassword(newPassword);
+ //发送修改密码请求
+ try {
+ const data = await require("POST", `/api/login/logout`, {
+ body: {
+ mobile_phone: mobile_phone,
+ region_code: regionCode,
+ veri_code: veriCode,
+ new_password: encryptedNewPassword,
+ },
+ });
+ if (data.ret === -1) {
+ Toast.show({
+ icon: "fail",
+ content: data.msg,
+ position: "top",
+ });
+ return;
+ }
+ Toast.show({
+ icon: "success",
+ content: "修改成功,请重新登录",
+ position: "top",
+ });
+ signOut();
+ } catch (error) {
+ console.error(error);
+ }
+ };
return (
@@ -43,24 +168,29 @@ export default function EditPassword() {
maxLength={11}
onChangeText={(value) => setMobilePhone(value)}
value={mobilePhone}
- style={{"--color":"#FFFFFF","--font-size":"16px"}}
+ style={{ "--color": "#FFFFFF", "--font-size": "16px" }}
/>
-
验证码
+
+ 验证码
+
setVeriCode(value)}
value={veriCode}
type="number"
- style={{"--placeholder-color":"#FFFFFF80","--font-size":"16px"}}
+ style={{
+ "--placeholder-color": "#FFFFFF80",
+ "--font-size": "16px",
+ }}
/>
-
新密码
+
+ 新密码
+
setNewPassword(value)}
value={newPassword}
- style={{"--placeholder-color":"#FFFFFF80","--font-size":"16px"}}
+ style={{
+ "--placeholder-color": "#FFFFFF80",
+ "--font-size": "16px",
+ }}
/>
-
确认密码
+
+ 确认密码
+
setConfirmPassword(value)}
value={confirmPassword}
- style={{"--placeholder-color":"#FFFFFF80","--font-size":"16px"}}
+ style={{
+ "--placeholder-color": "#FFFFFF80",
+ "--font-size": "16px",
+ }}
/>
diff --git a/app/my/setting/feedback/page.js b/app/my/setting/feedback/page.js
index c827fce..8982dd5 100644
--- a/app/my/setting/feedback/page.js
+++ b/app/my/setting/feedback/page.js
@@ -1,18 +1,62 @@
"use client";
import React, { useState } from "react";
-import { Button, TextArea } from "antd-mobile";
+import { Button, TextArea,Toast } from "antd-mobile";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import {
- faAngleLeft,
-} from "@fortawesome/free-solid-svg-icons";
+import { faAngleLeft } from "@fortawesome/free-solid-svg-icons";
import { useRouter } from "next/navigation";
import UploadImgs from "@/components/UploadImgs";
+import { get } from "@/utils/storeInfo";
export default function Feedback() {
const [value, setValue] = useState();
const [assets, setAssets] = useState([]);
const [isSubmitting, setIsSubmitting] = useState(false);
const router = useRouter();
+ //提交反馈
+ const handleSubmit = async () => {
+ if (!value) {
+ Toast.show({
+ icon: "fail",
+ content: "反馈内容不能为空",
+ position: "top",
+ });
+ return;
+ }
+ // const media = await multiUpload(assets);
+ console.log("media",{image_ids:assets,video_ids:[]})
+ // //提交数据
+ // setIsSubmitting(true);
+ // const media = await multiUpload(assets);
+ // const account = await get("account");
+ // try {
+ // const data = await require("POST", `/api/feedback/create`, {
+ // body: {
+ // mid: account.mid,
+ // discription: value,
+ // credentials: media,
+ // },
+ // });
+ // if (data.ret === -1) {
+ // Toast.show({
+ // icon: "fail",
+ // content: data.msg,
+ // position: "top",
+ // });
+ // return;
+ // }
+ // //提交成功后显示Toast并返回上一页
+ // Toast.show({
+ // icon: "success",
+ // content: "反馈提交成功",
+ // position: "top",
+ // });
+ // router.goBack();
+ // } catch (error) {
+ // console.error(error);
+ // } finally {
+ // setIsSubmitting(false);
+ // }
+ };
return (
@@ -40,14 +84,15 @@ export default function Feedback() {
截图或录屏(最多9张)
-
+
)}
diff --git a/app/space/setting/page.js b/app/space/setting/page.js
index c0d85bf..462f892 100644
--- a/app/space/setting/page.js
+++ b/app/space/setting/page.js
@@ -1,6 +1,6 @@
"use client";
-import React, { useEffect, useState, useRef } from "react";
+import React, { useEffect, useState, useCallback } from "react";
import { Image, Avatar, Divider, Dialog, Toast } from "antd-mobile";
import { useRouter, useSearchParams } from "next/navigation";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@@ -18,38 +18,81 @@ export default function Setting() {
let data = JSON.parse(decodeURIComponent(searchParams.get("data")));
setStreamerInfo(data);
}, []);
- const handleShowVideo = () => {
- Dialog.className = "videoMask";
- Dialog.show({
+ const handleShowDialog = () => {
+ const result = Dialog.show({
title: "是否确认退出空间?",
- content: (
-
- 一旦退出,您的空间成员身份将会被取消,若当前空间为付费空间,下次加入时,需要再次付费。请确保知晓以上内容后谨慎选择退出。
-
- ),
+ content:
+ "一旦退出,您的空间成员身份将会被取消,若当前空间为付费空间,下次加入时,需要再次付费。请确保知晓以上内容后谨慎选择退出。",
bodyStyle: {
- // background: "none",
maxHeight: "none",
width: "80vw",
- position: "absolute",
- top: "calc(50% - 50px)",
+ position: "fixed",
+ top: "200px",
left: "10vw",
+ "--text-color": "#fff",
+ color: "#fff",
},
+ // cancelText:"确认",
+ // confirmText:"取消",
+ style: {
+ "--text-color": "#fff",
+ },
+ closeOnAction: true,
actions: [
- {
- key: "submit",
- text: "确定",
- onClick: () => {
- i;
+ [
+ {
+ key: "submit",
+ text: "确认",
+ style: { color: "#ffffff80" },
+ onClick: handleExitSpace,
},
- },
- {
- key: "cancel",
- text: "取消",
- onClick: () => {},
- },
+ {
+ key: "close",
+ text: "取消",
+ bold: true,
+ style: { color: "#fff" },
+ onClick: () => {
+ Dialog?.close();
+ },
+ },
+ ],
],
});
+ if (result) {
+ Toast.show({ content: "点击了确认", position: "bottom" });
+ }
+ };
+ //格式化时间
+ const formatDate = useCallback((timestamp) => {
+ const date = new Date(timestamp * 1000);
+ const year = date.getFullYear();
+ const month = date.getMonth() + 1; // 月份从0开始,所以需要加1
+ const day = date.getDate();
+ return `${year}/${month}/${day}`;
+ }, []);
+ const handleExitSpace = async () => {
+ try {
+ const _data =
+ await require("POST", "/api/account_relation/count", {body:{
+ zid: streamerInfo?.id,
+ }});
+ if (_data.ret === -1) {
+ Toast.show({
+ icon: "fail",
+ content: _data.msg,
+ position: "top",
+ });
+ return;
+ }
+ Toast.show({
+ icon: "success",
+ content: "退出空间成功",
+ position: "top",
+ });
+ setTimeout(() => router.replace("HomeTab"), 500);
+ } catch (error) {
+ console.error(error);
+ }
};
return (
@@ -98,7 +141,7 @@ export default function Setting() {
router.back();
}}
/>
- {streamerInfo?.user_id}
+ {formatDate(streamerInfo?.ct)}
@@ -110,45 +153,14 @@ export default function Setting() {
className="flex justify-between"
>
分享空间
-
{
- router.back();
- }}
- />
+
- {
- const result = await Dialog.confirm({
- title: "是否确认退出空间?",
- content: "一旦退出,您的空间成员身份将会被取消,若当前空间为付费空间,下次加入时,需要再次付费。请确保知晓以上内容后谨慎选择退出。",
- bodyStyle: {
- maxHeight: "none",
- width: "80vw",
- position: "fixed",
- top: "200px",
- left: "10vw",
- },
- });
- if (result) {
- Toast.show({ content: "点击了确认", position: "bottom" });
- }
- }}
- >
+
退出空间
- {
- router.back();
- }}
- />
+
diff --git a/components/UploadImgs/index.js b/components/UploadImgs/index.js
index 20559a0..86ecf28 100644
--- a/components/UploadImgs/index.js
+++ b/components/UploadImgs/index.js
@@ -1,23 +1,105 @@
import React, { useState } from "react";
-import {ImageUploader,Toast} from "antd-mobile";
-export default function UploadImgs(props) {
+import { DotLoading, Image, ImageViewer } from "antd-mobile";
+import { uploadImage, uploadVideo } from "@/utils/upload";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { faAdd, faClose } from "@fortawesome/free-solid-svg-icons";
+export default function UploadImgs({ getImgs }) {
const maxCount = 6;
- const [fileList, setFileList] = useState([
- ]);
+ const [fileList, setFileList] = useState([]);
+ const [loading, setLoading] = useState(false);
+ const handleUploadImage = async (e) => {
+ let file = e.target.files[0];
+ console.log("ddddd", file.type);
+ if (!file) return;
+ setLoading(true);
+ if (file.type.indexOf("image/")!=-1) {
+ const image = await uploadImage(file);
+ getImgs((old) => [...old, image.id]);
+ setFileList((old) => [...old, image]);
+ }else if(file.type.indexOf("video/")!=-1){
+ const video = await uploadVideo(file);
+ getImgs((old) => [...old, video.id]);
+ setFileList((old) => [...old, video]);
+ }
+ setLoading(false);
+ };
+ const handleRemoveItem = (index) => {
+ console.log(index);
+ let newArr = [...fileList];
+ newArr.splice(index, 1);
+ setFileList(newArr);
+ };
+ const showPhotos = (images, index) => {
+ ImageViewer.Multi.show({
+ images: images.map(
+ (item) => "https://file.wishpaldev.tech/" + item?.src_id
+ ),
+ defaultIndex: index,
+ });
+ };
return (
- {
- Toast.show(`最多选择 ${maxCount} 张图片,你多选了 ${exceed} 张`);
- }}
- >
- +
-
+ // {
+ // Toast.show(`最多选择 ${maxCount} 张图片,你多选了 ${exceed} 张`);
+ // }}
+ // >
+ // +
+ //
+
+ {fileList.map((item, index) => {
+ return (
+
+
showPhotos(fileList, index)}
+ />
+ handleRemoveItem(index)}
+ >
+
+
+
+ );
+ })}
+ {loading && (
+
+ )}
+
+
+
);
}
+// export async function mockUpload(file) {
+// await sleep(3000)
+// return {
+// url: URL.createObjectURL(file),
+// }
+// }
diff --git a/utils/storeInfo.js b/utils/storeInfo.js
index 2d12e33..b00df55 100644
--- a/utils/storeInfo.js
+++ b/utils/storeInfo.js
@@ -2,7 +2,7 @@ export function save(key,value){
localStorage.setItem(key,value)
}
export function get(key){
- let data = localStorage.getItem("account");
+ let data = localStorage.getItem(key);
// console.log(key,data)
return data ? JSON.parse(data) : {};
diff --git a/utils/upload.js b/utils/upload.js
index a424b11..e6f3c65 100644
--- a/utils/upload.js
+++ b/utils/upload.js
@@ -90,8 +90,43 @@ async function calculateFileMetadata(file) {
});
}
+//获取上传失败时返回的id
+async function getFailId() {
+ const base = await baseRequest();
+ const signature = await generateSignature({
+ ...base,
+ });
+ try {
+ const response = await fetch(
+ `/api/upload_media_fail_config/list?signature=${signature}`,
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ ...base,
+ }),
+ }
+ );
+ const data = await response.json();
+ if (data.ret === -1) {
+ Toast.show({
+ type: "error",
+ text1: data.msg,
+ topOffset: 60,
+ });
+ return;
+ }
+ return data.data;
+ } catch (e) {
+ console.warn(e);
+ }
+}
+
//上传单张图片
export async function uploadImage(asset) {
+ console.log("uploadResponse",asset)
const auth = await getAuth(1);
try {
const formData = new FormData();
@@ -107,7 +142,6 @@ export async function uploadImage(asset) {
method: "POST",
body: formData,
});
-
if (uploadResponse.status === 200) {
// console.log(asset);
// debugger
@@ -119,14 +153,11 @@ export async function uploadImage(asset) {
w: info.width,
fmt: asset.type,
};
+
+
const base = baseRequest();
- const signature = generateSignature({
- mtype: 1,
- item: item,
- ...base,
- });
const response = await fetch(
- `/api/media/c_upload?signature=${signature}`,
+ `/api/media/c_upload`,
{
method: "POST",
headers: {
@@ -146,7 +177,7 @@ export async function uploadImage(asset) {
});
return;
}
- return data.data.ret_item.id;
+ return data.data.ret_item;
} else {
Toast.show({
content: "上传图片失败",
@@ -157,14 +188,108 @@ export async function uploadImage(asset) {
}
}
+//上传单个视频
+export async function uploadVideo(asset) {
+ const auth = await getAuth(2);
+ const fileType = "video";
+ const generateThumbnail = async () => {
+ try {
+ const videoCover = await VideoThumbnails.getThumbnailAsync(asset?.uri);
+ return videoCover;
+ } catch (e) {
+ console.warn(e);
+ }
+ };
+ try {
+ const formData = new FormData();
+ formData.append("name", auth.filename);
+ formData.append("policy", auth.policy);
+ formData.append("OSSAccessKeyId", auth.access_key_id);
+ formData.append("success_action_status", "200");
+ formData.append("signature", auth.signature);
+ formData.append("key", auth.directory + "/" + auth.filename);
+ formData.append("file", {
+ uri: asset?.uri,
+ name: asset?.filename,
+ type: fileType,
+ });
+
+ const uploadResponse = await fetch(auth.host, {
+ method: "POST",
+ body: formData,
+ });
+
+ if (uploadResponse.status === 200) {
+ const md5 = uploadResponse.headers.map.etag.substring(
+ 1,
+ uploadResponse.headers.map.etag.length - 1
+ );
+ const videoCover = await generateThumbnail();
+ const videoCoverId = await uploadImage(videoCover);
+ const item = {
+ src_id: auth.directory + "/" + auth.filename,
+ cover_id: videoCoverId,
+ md5: md5,
+ dur: asset?.duration,
+ fmt: fileType,
+ };
+ const base = baseRequest();
+ const response = await fetch(
+ `/api/media/c_upload`,
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ mtype: 2,
+ item: item,
+ ...base,
+ }),
+ }
+ );
+ const data = await response.json();
+ if (data.ret === -1) {
+ Toast.show({
+ type: "error",
+ text1: data.msg,
+ topOffset: 60,
+ });
+ return;
+ }
+ return data.data.ret_item.id;
+ } else {
+ Toast.show({
+ type: "error",
+ text1: "上传视频失败",
+ topOffset: 60,
+ });
+ const failId = await getFailId();
+ return failId?.video_id_for_upload_fail;
+ }
+ } catch (error) {
+ console.log("Error occurred while getting or uploading data:", error);
+ Toast.show({
+ type: "error",
+ text1: "上传视频失败",
+ topOffset: 60,
+ });
+ const failId = await getFailId();
+ return failId?.video_id_for_upload_fail;
+ }
+}
+
+
//上传多个图片
export async function multiUploadImage(assets) {
+ console.log("assets",assets)
let ids = { image_ids: [], video_ids: [] };
await Promise.all(
- assets.map(async (asset) => {
+ assets.forEach(async (asset) => {
const id = await uploadImage(asset);
ids.image_ids.push(id);
})
);
+
return ids;
}