소스 검색

修改小程序支付

plg 7 달 전
부모
커밋
a2251457a8

+ 61 - 9
src/App.vue

@@ -1,20 +1,72 @@
 <script setup lang="ts">
-import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
+import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
 
-onLaunch(() => {
-  console.log('App Launch')
-})
+// onLaunch((options) => {
+//   console.log(decodeURIComponent(options?.query.scene));
+//   console.log("App Launch");
+// });
 onShow(() => {
-  console.log('App Show')
-})
+  console.log("App Show");
+  //调用  版本更新
+});
 onHide(() => {
-  console.log('App Hide')
-})
+  console.log("App Hide");
+});
+const autoUpdate = () => {
+  if (uni.canIUse("getUpdateManager")) {
+    const updateManager = uni.getUpdateManager();
+    updateManager.onCheckForUpdate(function (res) {
+      if (res.hasUpdate) {
+        updateManager.onUpdateReady(function () {
+          uni.showModal({
+            title: "更新提示",
+            content: "新版本已经准备好,是否重启应用?",
+            showCancel: false,
+            success: function (res) {
+              if (res.confirm) {
+                updateManager.applyUpdate();
+              } else if (res.cancel) {
+                uni.showModal({
+                  title: "温馨提示~",
+                  content: "本次版本更新涉及到新的功能添加,旧版本无法正常访问的哦~",
+                  success: function (res) {
+                    // autoUpdate();
+                    // return;
+                    //第二次提示后,强制更新
+                    if (res.confirm) {
+                      // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
+                      updateManager.applyUpdate();
+                    } else if (res.cancel) {
+                      //重新回到版本更新提示
+                      autoUpdate();
+                    }
+                  },
+                });
+              }
+            },
+          });
+          updateManager.onUpdateFailed(function () {
+            // 新的版本下载失败
+            uni.showModal({
+              title: "已经有新版本了哟~",
+              content: "新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~",
+            });
+          });
+        });
+      }
+    });
+  } else {
+    uni.showModal({
+      title: "提示",
+      content: "当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。",
+    });
+  }
+};
 </script>
 
 <style lang="scss">
 // 字体图标
-@import '@/styles/fonts.scss';
+@import "@/styles/fonts.scss";
 
 view,
 navigator,

+ 57 - 2
src/components/ShuiWuGetPhone.vue

@@ -1,7 +1,56 @@
 <script setup lang="ts">
-import { ref } from "vue";
+import { onMounted, ref, reactive } from "vue";
+import { userLoginApi, getUserPhoneApi } from "@/services/home";
+import { useMemberStore } from "@/stores/";
+import type { LoginParams, GetPhoneParams } from "@/types/home";
+import { login } from "@/hooks/useIsLogin";
+const useMember = useMemberStore();
 const popup = ref<any>();
+
+const userInfoMsg = reactive<LoginParams>({
+  code: "",
+});
+
+onMounted(() => {
+  console.log("登录");
+});
+//获取手机号
+const getPhoneNumber = (e: any) => {
+  console.log(e);
+  //获取到动态令牌后将动态令牌传输到后台方法
+  //同时需要将获取到的openId传输给后台
+  const params = {
+    openId: useMember.userInfo.openId,
+    code: e.detail.code,
+  };
+  getUserPhone(params);
+};
+const getUserPhone = async (val: GetPhoneParams) => {
+  const res = await getUserPhoneApi(val);
+
+  useMember.userInfo.phone = res.data;
+
+  login().then((res) => {
+    //这时可以查询是否授权
+
+    if (useMember.userInfo.isAuth == "0") {
+      uni.showToast({
+        title: "登录成功,手机未授权",
+        icon: "none",
+      });
+    }
+  });
+  close();
+  //获取到手机号后
+  //将缓存里的手机号替换为最新的
+};
+
+//拿到code 向后台请求openId   session_key
+
 const open = () => {
+  login().then((res: any) => {
+    userInfoMsg.code = res.code;
+  });
   popup.value.open("bottom");
 };
 const close = () => {
@@ -47,7 +96,13 @@ defineExpose({
 
         <view class="welcome">欢迎登录税务风险检测</view>
         <view class="serve">登录后可享受更好的服务</view>
-        <button :disabled="!agree">立即登录</button>
+        <button
+          :disabled="!agree"
+          open-type="getPhoneNumber"
+          @getphonenumber="getPhoneNumber"
+        >
+          点击登录
+        </button>
         <view class="clause">
           <label class="radio">
             <radio value="r1" :checked="agree" @click="radioChange" />点击即表示同意

+ 79 - 0
src/hooks/useIsLogin.ts

@@ -0,0 +1,79 @@
+//判断用户是否授权、、或者是否登录
+
+import { userLoginApi } from '@/services/home'
+import type { LoginParams } from '@/types/home'
+import { useMemberStore } from '@/stores/'
+import { rejects } from 'assert'
+
+const useMember = useMemberStore()
+
+//当用户已授权手机号、、或者已登录
+const home = '/home/banner'
+
+//登录但是我返回的是code  登录凭证
+export const login = () => {
+  return new Promise((resolve, reject) => {
+    uni.login({
+      provider: 'weixin',
+      success: (res) => {
+        console.log(res)
+        const re = <LoginParams>{ code: res.code }
+        userLogin(re)
+        console.log('login')
+        resolve(re)
+      },
+      fail: (error) => {
+        reject(error)
+      },
+    })
+  })
+}
+
+const userLogin = async (code: LoginParams) => {
+  const res = await userLoginApi(code)
+  //存储token
+  //存储用户信息
+  useMember.token = res.data.token
+  console.log('userLogin')
+  // if (res.data.user.isAuth == '0') {
+  // }
+  useMember.saveUserInfo(res.data.user)
+
+  return code.code
+}
+
+//应该再写一个返回用户信息
+export const loginUser = () => {
+  return new Promise((resolve, reject) => {
+    uni.login({
+      provider: 'weixin',
+      success: (res) => {
+        console.log(res)
+        const re = <LoginParams>{ code: res.code }
+        userLoginApi(re).then((res) => {
+          //此时这个方法执行完了
+          //查看返回的数据
+          useMember.token = res.data.token
+          useMember.saveUserInfo(res.data.user)
+          resolve(res.data.user.id)
+        })
+      },
+      fail: (error) => {
+        reject(error)
+      },
+    })
+  })
+}
+
+// const loginUserInfo = async (code: LoginParams) => {
+//   const res = await userLoginApi(code)
+//   //存储token
+//   //存储用户信息
+//   useMember.token = res.data.token
+//   console.log(res)
+//   // if (res.data.user.isAuth == '0') {
+//   // }
+//   useMember.saveUserInfo(res.data.user)
+
+//   return code.code
+// }

+ 10 - 2
src/manifest.json

@@ -18,7 +18,8 @@
         },
         /* 模块配置 */
         "modules" : {
-            "Share" : {}
+            "Share" : {},
+            "Payment" : {}
         },
         /* 应用发布信息 */
         "distribute" : {
@@ -51,6 +52,13 @@
                         "appid" : "wxf9cf2808608b6781",
                         "UniversalLinks" : ""
                     }
+                },
+                "payment" : {
+                    "weixin" : {
+                        "__platform__" : [ "ios", "android" ],
+                        "appid" : "wxf9cf2808608b6781",
+                        "UniversalLinks" : ""
+                    }
                 }
             }
         }
@@ -59,7 +67,7 @@
     "quickapp" : {},
     /* 小程序特有相关 */
     "mp-weixin" : {
-        "appid" : "wxf9cf2808608b6781",
+        "appid" : "wx25c982b905769a23",
         "setting" : {
             "urlCheck" : false
         },

+ 8 - 0
src/pages.json

@@ -27,6 +27,14 @@
         // "navigationStyle": "custom"
       }
 
+    },
+    {
+      "path": "pages/index/pay",
+      "style": {
+        "navigationBarTitleText": "用户支付",
+        "navigationStyle": "custom"
+      }
+
     },
     {
       "path": "pages/my/my",

+ 10 - 1
src/pages/index/components/HomeTabs.vue

@@ -1,7 +1,16 @@
 <script setup lang="ts">
+import { useMemberStore } from "@/stores";
+const userInfo = useMemberStore();
 const emit = defineEmits(["jumpInvite"]);
 const inviteUserFun = () => {
-  emit("jumpInvite");
+  //判断是否是授权了
+  //如果没有授权,点击按钮择跳转授权页面
+  if (userInfo.userInfo.isAuth == "0") {
+    emit("jumpInvite");
+  } else {
+    //跳转到生成海报页面
+    uni.navigateTo({ url: "/pages/index/inviteUser" });
+  }
 };
 </script>
 <template>

+ 10 - 1
src/pages/index/index.vue

@@ -1,11 +1,20 @@
 <script setup lang="ts">
 import HomeTabs from "./components/HomeTabs.vue";
 import HomeList from "./components/HomeList.vue";
-import { ref, reactive } from "vue";
+import { ref, reactive, onMounted } from "vue";
+import { login } from "@/hooks/useIsLogin";
+import { onShow } from "@dcloudio/uni-app";
 const companyName = ref<string>("");
 
 const phoneGet = ref<any>();
 
+onMounted(() => {
+  //我来了
+});
+onShow(() => {
+  console.log("onshow");
+  login();
+});
 //调用子组件
 const phoneGetFun = () => {
   phoneGet.value.open();

+ 193 - 20
src/pages/index/inviteUser.vue

@@ -1,9 +1,129 @@
 <script setup lang="ts">
+import { imgUrl } from "@/utils/http";
 import { ref } from "vue";
+import { useMemberStore } from "@/stores";
+import { createPosterApi } from "@/services/home";
+import type { CreatePo } from "@/types/home";
+const userInfo = useMemberStore();
 const title = ref<string>("");
 const duration = ref<number>();
 const price = ref<number>();
 const num = ref<number>();
+//海报
+const placard = ref<string>();
+placard.value = userInfo.userInfo.posterBackground;
+
+//是否是新生成的海报带二维码
+const isCreatePaster = ref<boolean>(false);
+//调用接口得到图片海报路径
+//更换壁纸
+const changeImage = () => {
+  uni.chooseImage({
+    success: (chooseImageRes) => {
+      const tempFilePaths = chooseImageRes.tempFilePaths;
+      uni.uploadFile({
+        url: "/file/customUpload", //仅为示例,非真实的接口地址
+        filePath: tempFilePaths[0],
+        name: "file",
+        success: (uploadFileRes) => {
+          let photo = `${imgUrl}${JSON.parse(uploadFileRes.data).data}`;
+          placard.value = photo;
+          isCreatePaster.value = false;
+        },
+      });
+    },
+  });
+};
+//生成海报
+const createPlacard = () => {
+  console.log(duration.value);
+  if (title.value == "") {
+    uni.showToast({
+      title: "请填写标题",
+      icon: "none",
+    });
+    return;
+  }
+  if (typeof duration.value == "undefined") {
+    uni.showToast({
+      title: "请填写时长",
+      icon: "none",
+    });
+    return;
+  }
+
+  if (typeof price.value == "undefined") {
+    uni.showToast({
+      title: "请填写价格",
+      icon: "none",
+    });
+    return;
+  }
+  if (typeof num.value == "undefined") {
+    uni.showToast({
+      title: "请填写次数",
+      icon: "none",
+    });
+    return;
+  }
+  if (num.value == 0 || price.value == 0 || duration.value == 0) {
+    uni.showToast({
+      title: "时长|价格|次数不能为0",
+      icon: "none",
+    });
+    return;
+  }
+  //判断图片是否改变
+  createPoster({
+    userId: userInfo.userInfo.id,
+    title: title.value,
+    effectiveDays: duration.value as number,
+    amount: price.value as number,
+    times: num.value as number,
+    background: placard.value,
+  });
+  //调用生成海报的方法
+};
+const createPoster = async (val: CreatePo) => {
+  const res = await createPosterApi(val);
+  console.log("海报");
+  console.log(res);
+  if (res.data == "2001") {
+    uni.showToast({
+      title: res.msg,
+      icon: "fail",
+    });
+  } else {
+    // console.log(res.data);
+    placard.value = `${imgUrl}${res.data}`;
+    isCreatePaster.value = true;
+  }
+};
+//下载图片
+const saveLocal = () => {
+  //下载图片
+  // uni.showLoading();
+  let url: string = placard.value as string;
+  uni.downloadFile({
+    url: url, //仅为示例,并非真实的资源
+    success: (res) => {
+      console.log(res);
+      if (res.statusCode === 200) {
+        uni.saveImageToPhotosAlbum({
+          // 然后调用这个方法
+          filePath: res.tempFilePath,
+          success: (res) => {
+            // uni.hideLoading();
+            uni.showToast({
+              title: "已保存至相册",
+              icon: "success",
+            });
+          },
+        });
+      }
+    },
+  });
+};
 </script>
 <template>
   <view class="invite_user">
@@ -15,6 +135,7 @@ const num = ref<number>();
             ><uni-easyinput
               type="text"
               :inputBorder="false"
+              :clearable="false"
               v-model="title"
               placeholder="请输入标题"
             ></uni-easyinput
@@ -23,41 +144,68 @@ const num = ref<number>();
       </uni-col>
       <uni-col :span="12">
         <view class="user_input">
-          <view class="user_out">
-            <view class="user_font">时长</view>
-            <view>
-              <uni-number-box
-                :min="0"
-                v-model="duration"
-                placeholder="请输入时长"
-              /> </view
+          <view class="user_font">时长</view>
+          <view
+            ><uni-easyinput
+              type="number"
+              :clearable="false"
+              :inputBorder="false"
+              v-model="duration"
+              placeholder="请输入时长(天)"
+            ></uni-easyinput
           ></view>
-
-          <view class="user_font_unit">天</view>
         </view>
       </uni-col>
     </uni-row>
     <uni-row style="margin-top: 100rpx">
       <uni-col :span="12">
         <view class="user_input">
-          <view class="user_out">
-            <view class="user_font">价格</view>
-            <uni-number-box :min="0" v-model="price" placeholder="请输入价格"
-          /></view>
-
-          <view class="user_font_unit">元</view>
+          <view class="user_font">价格</view>
+          <view
+            ><uni-easyinput
+              type="number"
+              :clearable="false"
+              :inputBorder="false"
+              v-model="price"
+              placeholder="请输入价格(元)"
+            ></uni-easyinput
+          ></view>
         </view>
       </uni-col>
       <uni-col :span="12">
-        <view class="user_input_time">
+        <view class="user_input">
           <view class="user_font">次数</view>
-          <uni-number-box :min="0" v-model="duration" placeholder="请输入次数" />
+          <view
+            ><uni-easyinput
+              type="number"
+              :clearable="false"
+              :inputBorder="false"
+              v-model="num"
+              placeholder="请输入次数"
+            ></uni-easyinput
+          ></view>
         </view>
       </uni-col>
     </uni-row>
+    <button class="mini-btn" size="mini" @click="changeImage">跳转支付</button>
     <view class="button_group">
-      <button class="mini-btn" type="default" size="mini">更换壁纸</button>
-      <button class="mini-btn" type="default" size="mini">生成海报</button>
+      <button class="mini-btn" size="mini" @click="changeImage">更换壁纸</button>
+      <button class="mini-btn" size="mini" @click="createPlacard">生成海报</button>
+    </view>
+    <view class="remark_user">备注:更换壁纸请上传720*1280分辨率的壁纸,大小在3M以下</view>
+    <view>
+      <image
+        :show-menu-by-longpress="isCreatePaster"
+        mode="aspectFill"
+        style="width: 720rpx; height: 1280rpx"
+        :src="placard"
+      ></image
+    ></view>
+    <view class="remark_eweima"
+      >备注:可以长按分享二维码,或点击你保存至手机,请保管好二维码以防他人使用</view
+    >
+    <view style="text-align: center; padding: 0rpx 100rpx">
+      <button class="save_button" size="mini" @click="saveLocal">保存至本地</button>
     </view>
   </view>
 </template>
@@ -70,6 +218,31 @@ page {
   width: 100%;
   padding: 10rpx 15rpx;
   background: rgb(243, 250, 248);
+  .remark_user {
+    color: #000000;
+    opacity: 0.4;
+    font-size: 26rpx;
+    margin-top: 20rpx;
+    margin-bottom: 10rpx;
+  }
+  .remark_eweima {
+    text-align: center;
+    color: #000000;
+    opacity: 0.4;
+    font-size: 26rpx;
+    margin-top: 20rpx;
+    margin-bottom: 10rpx;
+    padding: 0rpx 40rpx;
+  }
+  .save_button {
+    text-align: center;
+    background: linear-gradient(#ffffff, rgb(125, 123, 226));
+    color: #ffffff;
+    width: 100%;
+    font-size: 36rpx;
+    margin-top: 40rpx;
+    margin-bottom: 100rpx;
+  }
   .button_group {
     display: flex;
     flex-direction: row;

+ 233 - 0
src/pages/index/pay.vue

@@ -0,0 +1,233 @@
+<script setup lang="ts">
+import { onLoad, onUnload } from "@dcloudio/uni-app";
+import { ref, reactive } from "vue";
+import {
+  createOrderApi,
+  payAppointmentApi,
+  queryOrderStatusApi,
+  queryParamsApi,
+} from "@/services/home";
+import type { QueryPa } from "@/types/home";
+import HomeList from "./components/HomeList.vue";
+import { loginUser } from "@/hooks/useIsLogin";
+
+//1 未支付   --可查看全部信息
+//2 openId相等  但是状态是支付中  --可查看全部状态
+//3 openId不相等  状态是别人在支付中 --不可查看任何信息
+//4 openId 相等  但是已支付  --不再支付可查看生成的报告
+//5 openId 不相等  别人已支付  --不可查看任何信息
+
+/**
+ * 总结  当返回状态是
+ * 1或2时--按钮是微信支付---且列表显示--全部信息展示
+ * 3和5时 所有信息不展示
+ * 4时 按钮为查看风险评估
+ *
+ */
+
+//获取到的传输过来的唯一值
+const params = reactive<any>({
+  title: "", //标题
+  num: "", //剩余次数
+  time: "", //有效截止日期
+  flag: "", //当前订单的状态
+});
+
+// const userId = ref<string>("");
+//调用查询参数需要的入参
+const scene = ref<QueryPa>({ scene: "", userId: "" });
+const orderId = ref<string>("");
+onLoad((options) => {
+  //获取的二维码中得到的参数信息
+  console.log(decodeURIComponent(options?.scene));
+  scene.value.scene = decodeURIComponent(options?.scene);
+  loginUser().then((res) => {
+    //这时已经有返回信息了且用户数据已经
+    scene.value.userId = res as string;
+    //获取到userId了
+    queryParams(scene.value);
+  });
+});
+
+//查询 根据唯一键值对
+const queryParams = async (val: QueryPa) => {
+  const res = await queryParamsApi(val);
+
+  params.flag = res.data.flag;
+  if (params.flag == 3 || params.flag == 5) {
+    return;
+  }
+  params.title = res.data.title;
+  params.num = res.data.times;
+
+  params.time = formatterData(res.data.createDate, res.data.effectiveDays);
+};
+
+//有效日期
+const formatterData = (date: any, day: any) => {
+  //将data日期格式化为初始的毫秒值
+  //将day 日期格式化为day
+
+  let dateF = new Date(date).getTime();
+  let dayF = day * 24 * 60 * 60 * 1000;
+  console.log(dateF);
+  console.log(dayF);
+  let dataN = dateF + dayF;
+  //然后将毫秒值转化为具体时间
+  let dataNew = new Date(dataN);
+  let y = dataNew.getFullYear();
+  let m =
+    dataNew.getMonth() + 1 < 10 ? "0" + (dataNew.getMonth() + 1) : dataNew.getMonth() + 1;
+
+  let d = dataNew.getDate() < 10 ? "0" + dataNew.getDate() : dataNew.getDate();
+  return y + "-" + m + "-" + d;
+};
+
+//1先生成订单号
+//2订单号生成后调用后台获取核心参数  核心参数获取到以后
+//3调用位置支付、、 查看成功与否
+//4如果是成功支付和用户取消了订单
+//5否则循环调用查询支付接口
+//支付完成后进行下边的逻辑--开始查询报告
+
+//点击支付按钮生成的方法
+const payButton = () => {
+  //先调用订单生成
+  //creatOrderFun()
+};
+//生成订单号
+const creatOrderFun = async (val: any) => {
+  const res = await createOrderApi(val);
+  //获取到订单号了
+
+  //然后调用预支付接口后去核心数据
+  //payFun(val)
+};
+//支付接口调用
+//调用后台接口返回订单号
+//调用后台接口返回  下单核心数据
+const payFun = async (val: any) => {
+  const res = await payAppointmentApi(val);
+  //核心参数返回后
+  //调用微信支付方法
+  uni.requestPayment({
+    ...val,
+    success: (res: any) => {
+      if (res) {
+        console.log(res);
+        if (res.errMsg == "requestPayment:ok") {
+          //
+          console.log("支付成功");
+        }
+      }
+    },
+    fail: (res: any) => {
+      console.log(res);
+      if (res.errMsg == "requestPayment:fail cancel") {
+        console.log("用户取消了支付");
+      } else {
+        queryOrderFor();
+        //调用支付失败的具体原因
+        //这时是不是就应该定时器调用订单状态
+      }
+    },
+  });
+};
+
+//查询订单状态
+const queryOrderStatus = async (val: any) => {
+  const res = await queryOrderStatusApi(val);
+  //判定返回参数
+  //如果订单完成了
+  //如果是满了返回了
+  //需要去掉定时器
+  clearInterval(timeMe.value);
+};
+//定时器参数
+const timeMe = ref<any>();
+//创建一个定时器
+const queryOrderFor = () => {
+  //进来的时候清除定时器
+  clearInterval(timeMe.value);
+  timeMe.value = setInterval(() => {
+    //嗲用方法
+    queryOrderStatus({});
+  }, 3000);
+};
+
+//销毁页面
+onUnload(() => {
+  //来清除定时器
+  clearInterval(timeMe.value);
+});
+</script>
+<template>
+  <view class="payBg">
+    <ShuiWuTop />
+    <view class="pay_params">
+      <view class="pay_card_title1">
+        {{ params.title }}
+      </view>
+      <view class="pay_card_num"> 剩余生成次数:{{ params.num }} </view>
+      <view class="pay_card_time"> 有效日期:{{ params.time }} </view>
+    </view>
+    <view v-show="params.flag == 1 || params.flag == 2"
+      ><button class="pay_button" @click="payButton">立即支付</button></view
+    >
+    <view v-show="params.flag == 4"
+      ><button class="detection_button">税务风险检测</button></view
+    >
+
+    <view v-show="params.flag == 4"><HomeList class="home_list_com" /></view>
+  </view>
+</template>
+<style lang="scss">
+page {
+  height: 100%;
+}
+.payBg {
+  background-color: rgb(243, 250, 248);
+  width: 750rpx;
+  height: 100%;
+  padding: 0rpx 20rpx;
+  .pay_params {
+    border-radius: 20rpx;
+    color: #ffffff;
+    margin-top: 60rpx;
+    padding: 20rpx 40rpx;
+    background: linear-gradient(#bbc0ee, #55459e);
+    display: flex;
+    flex-direction: column;
+    .pay_card_title1 {
+      font-size: 40rpx;
+      padding-top: 20rpx;
+      padding-bottom: 40rpx;
+      padding-left: 20rpx;
+    }
+    .pay_card_num {
+      font-size: 26rpx;
+      padding-left: 20rpx;
+      margin-top: 20rpx;
+    }
+    .pay_card_time {
+      font-size: 26rpx;
+      padding-left: 20rpx;
+      margin-top: 20rpx;
+      margin-bottom: 40rpx;
+    }
+  }
+  .pay_button {
+    color: #ffffff;
+    border-radius: 20rpx;
+    margin-top: 40rpx;
+    width: 100%;
+    background: linear-gradient(#bbc0ee, #55459e);
+  }
+  .detection_button {
+    border-radius: 20rpx;
+    color: #ffffff;
+    width: 100%;
+    background: linear-gradient(#bb8e2d, #c7ca11);
+  }
+}
+</style>

+ 14 - 14
src/pages/my/my.vue

@@ -68,29 +68,29 @@ const exit = () => {
     <ShuiWuTop />
     <view class="home_top"> 我的 </view>
     <view class="company_top"
-      ><image
-        class="company_image"
-        src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/shuijiao.jpg"
-      ></image>
-      <view>xxxxxxx公司</view>
+      ><image class="company_image" :src="memberStore.userInfo.channelAvatar"></image>
+      <view>{{
+        memberStore.userInfo.channelName == null ? "" : memberStore.userInfo.channelName
+      }}</view>
     </view>
     <view class="my_info">
       <view class="info_out">
-        <image
-          class="user_image"
-          src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/shuijiao.jpg"
-        ></image>
+        <image class="user_image" :src="memberStore.userInfo.photoPath"></image>
         <view class="user_name">
-          <view class="user_name_detail">张丽莎</view>
-          <view class="user_name_detail">岗位:&nbsp;&nbsp;销售</view>
+          <view class="user_name_detail">{{ memberStore.userInfo.userName }}</view>
+          <view class="user_name_detail"
+            >岗位:&nbsp;&nbsp;{{ memberStore.userInfo.job }}</view
+          >
         </view>
       </view>
       <view class="info_detail" style="margin-top: 25rpx"
-        >联系电话:&nbsp;&nbsp;18595924672
+        >联系电话:&nbsp;&nbsp;{{
+          memberStore.userInfo.phone == "NaN" ? "" : memberStore.userInfo.phone
+        }}
       </view>
-      <view class="info_detail">邮箱:&nbsp;&nbsp;1728114119@qq.com </view>
+      <view class="info_detail">邮箱:&nbsp;&nbsp;{{ memberStore.userInfo.mail }}</view>
       <view class="info_detail" style="margin-bottom: 15rpx"
-        >公司地址:&nbsp;&nbsp;自内蒙古自治区</view
+        >公司地址:&nbsp;&nbsp;{{ memberStore.userInfo.compAddress }}</view
       >
       <view class="info_edit">
         <button class="button_edit" @click="editUser">编辑</button>

+ 94 - 61
src/pages/my/myEdit.vue

@@ -1,47 +1,66 @@
 <script setup lang="ts">
 import { ref, reactive } from "vue";
-const imageStyles = reactive({
-  width: 64,
-  height: 64,
-  border: {
-    radius: "50%",
-  },
-});
+import { imgUrl } from "../../utils/http";
+import { useMemberStore } from "@/stores";
+import { userInfoUpdateApi } from "@/services/my";
+import type { UserInfoT } from "@/types/my";
+
 const valiFormData = reactive({
-  name: "",
-  age: "",
-  introduction: "",
-});
-const rules = reactive({
-  rules: {
-    name: {
-      rules: [
-        {
-          required: true,
-          errorMessage: "名字不能为空",
-        },
-      ],
-    },
-    age: {
-      rules: [
-        {
-          required: true,
-          errorMessage: "年龄不能为空",
-        },
-        {
-          format: "number",
-          errorMessage: "年龄只能输入数字",
-        },
-      ],
-    },
-  },
+  userName: "",
+  mail: "",
 });
+
+//从缓存取个人用户信息
+const userInfo = useMemberStore();
+//将缓存里边取出来的东西拿出来//放在这个用户的字段里
+valiFormData.userName = userInfo.userInfo.userName;
+valiFormData.mail = userInfo.userInfo.mail;
 const valiForm = ref();
 const submit = (ref: string) => {
-  uni.showToast({
-    title: "请填写名称",
-    duration: 2000,
-    icon: "error",
+  if (valiFormData.userName == "") {
+    uni.showToast({
+      title: "请填写名称",
+      duration: 2000,
+      icon: "error",
+    });
+    return;
+  }
+  userInfoUpdate({
+    id: userInfo.userInfo.id,
+    avatar: userInfo.userInfo.photoPath,
+    userName: valiFormData.userName,
+    mail: valiFormData.mail,
+  });
+};
+const userInfoUpdate = async (val: UserInfoT) => {
+  const res = await userInfoUpdateApi(val);
+  //修改用户信息
+  console.log("修改用户信息");
+  if (res.code) {
+    uni.showToast({
+      title: "修改成功",
+      duration: 2000,
+      icon: "success",
+    });
+  }
+};
+
+//获取用户头像
+const getAvatar = (e: any) => {
+  //需要调用上传接口将图片上传至自己的服务器
+  //然后返回个地址就是头像的地址
+  uni.uploadFile({
+    url: "/file/customUpload",
+    filePath: e.detail.avatarUrl,
+    name: "file",
+    success: (res) => {
+      let photo = `${imgUrl}${JSON.parse(res.data).data}`;
+      console.log(photo);
+
+      userInfo.userInfo.photoPath = photo;
+      console.log(userInfo.userInfo);
+      userInfo.saveUserInfo(userInfo.userInfo);
+    },
   });
 };
 //提交并进行表单校验
@@ -63,16 +82,34 @@ const submit = (ref: string) => {
 </script>
 <template>
   <view class="my_edit">
-    <uni-forms
-      label-position="right"
-      ref="valiForm"
-      :modelValue="valiFormData"
-      :rules="rules.rules"
-    >
+    <uni-forms label-position="right" ref="valiForm" :modelValue="valiFormData">
       <uni-forms-item label="">
         <view class="avatar_class">
           <view>头像</view>
-          <uni-file-picker
+          <!-- 获取用户头像 -->
+          <!-- 获取用户头像 -->
+          <view>
+            <button class="avatar-btn" open-type="chooseAvatar" @chooseavatar="getAvatar">
+              <image
+                style="
+                  width: 80rpx;
+                  height: 80rpx;
+                  background-color: #eeeeee;
+                  border-radius: 50%;
+                "
+                :src="userInfo.userInfo.photoPath"
+              ></image>
+              <!-- <u-avatar
+              @click="handleAva"
+              class="avatar"
+              size="80"
+                 :src="userInfo.userInfo.photo"
+              :src="userStore.userAvatar"
+            ></u-avatar> -->
+            </button></view
+          >
+
+          <!-- <uni-file-picker
             style="width: 100rpx"
             limit="1"
             :del-icon="false"
@@ -80,40 +117,36 @@ const submit = (ref: string) => {
             :imageStyles="imageStyles"
             file-mediatype="image"
             >&nbsp;</uni-file-picker
-          >
+          > -->
+          <!-- <image
+            @click="getAvatarFun"
+            style="width: 200px; height: 200px; background-color: #eeeeee"
+            src=""
+          ></image> -->
         </view>
       </uni-forms-item>
       <uni-forms-item label="">
         <view class="name_class">
           <view>名字</view>
           <uni-easyinput
+            :clearable="false"
             :inputBorder="false"
-            v-model="valiFormData.name"
+            v-model="valiFormData.userName"
             placeholder="请输入名字"
           ></uni-easyinput>
         </view>
       </uni-forms-item>
       <uni-forms-item label="">
         <view class="name_class">
-          <view>岗位 </view>
-          <uni-easyinput :inputBorder="false" placeholder="请输入岗位"></uni-easyinput>
-        </view>
-      </uni-forms-item>
-      <uni-forms-item label="">
-        <view class="name_class">
-          <view> 联系电话 </view>
+          <view> 邮箱 </view>
           <uni-easyinput
             :inputBorder="false"
-            placeholder="请输入联系电话"
+            :clearable="false"
+            v-model="valiFormData.mail"
+            placeholder="请输入邮箱"
           ></uni-easyinput>
         </view>
       </uni-forms-item>
-      <uni-forms-item label="">
-        <view class="name_class">
-          <view> 邮箱 </view>
-          <uni-easyinput :inputBorder="false" placeholder="请输入邮箱"></uni-easyinput>
-        </view>
-      </uni-forms-item>
       <uni-forms-item></uni-forms-item>
     </uni-forms>
     <button class="submit_user" @click="submit('valiForm')">提交</button>

+ 84 - 1
src/services/home.ts

@@ -1,5 +1,5 @@
 // import http from '@/utils/http'
-import type { MusicFInd, TypeList } from '@/types/home'
+import type { CreatePo, GetPhoneParams, LoginParams, MusicFInd, TypeList } from '@/types/home'
 import { http } from '@/utils/http'
 
 //首页轮播图路径
@@ -9,6 +9,26 @@ const home = '/home/banner'
 const musicType = '/type/find'
 //查询具体的音乐
 const musicFindUrl = '/music/find'
+
+//用户登录
+const userLoginUrl = '/user/login'
+//获取用户手机号
+const getUserPhoneUrl = '/user/getPhoneNumber'
+
+//生成海报
+const createPosterUrl = '/link/save'
+
+//根据scene 查询传输参数路径
+const queryParamsUrl = '/link/check'
+
+//生成订单号
+const createOrderUrl = ''
+//预支付接口
+const payAppointmentUrl = ''
+
+//订单号查询
+const queryOrderStatusUrl = ''
+
 export const getHomeApi = (distributionSite = 1) => {
   return http<TypeList[]>({
     method: 'GET',
@@ -33,3 +53,66 @@ export const musicFindApi = (id: string) => {
     url: musicFindUrl + `/${id}`,
   })
 }
+
+//用户登录
+export const userLoginApi = (val: LoginParams) => {
+  return http<any>({
+    method: 'POST',
+    url: userLoginUrl,
+    data: { ...val },
+  })
+}
+
+//获取用户手机号
+export const getUserPhoneApi = (val: GetPhoneParams) => {
+  return http<any>({
+    method: 'POST',
+    url: getUserPhoneUrl,
+    data: { ...val },
+  })
+}
+
+//生成海报接口
+export const createPosterApi = (val: CreatePo) => {
+  return http<any>({
+    method: 'POST',
+    url: createPosterUrl,
+    data: { ...val },
+  })
+}
+
+//根据查询scene 查询传输参数的 方法
+export const queryParamsApi = (val: any) => {
+  return http<any>({
+    method: 'GET',
+    url: `${queryParamsUrl}/${val.scene}/${val.userId}`,
+    // data: { ...val },
+  })
+}
+
+//生成订单号
+export const createOrderApi = (val: any) => {
+  return http<any>({
+    method: 'POST',
+    url: createOrderUrl,
+    data: { ...val },
+  })
+}
+
+//调用后去后台核心参数--预支付
+export const payAppointmentApi = (val: any) => {
+  return http<any>({
+    method: 'POST',
+    url: payAppointmentUrl,
+    data: { ...val },
+  })
+}
+
+//根据订单号查询用户订单状况
+export const queryOrderStatusApi = (val: any) => {
+  return http<any>({
+    method: 'POST',
+    url: queryOrderStatusUrl,
+    data: { ...val },
+  })
+}

+ 14 - 0
src/services/my.ts

@@ -0,0 +1,14 @@
+import type { UserInfoT } from '@/types/my'
+import { http } from '@/utils/http'
+
+const myInfoUpdateUrl = '/user/update/staff'
+
+export const userInfoUpdateApi = (val: UserInfoT) => {
+  return http({
+    method: 'POST',
+    url: myInfoUpdateUrl,
+    data: {
+      ...val,
+    },
+  })
+}

+ 49 - 2
src/stores/modules/member.ts

@@ -1,5 +1,5 @@
 import { defineStore } from 'pinia'
-import { ref } from 'vue'
+import { reactive, ref } from 'vue'
 
 // 定义 Store
 export const useMemberStore = defineStore(
@@ -8,7 +8,51 @@ export const useMemberStore = defineStore(
     // 会员信息
     const profile = ref<any>()
     const token = ref<any>()
-
+    const userInfo = ref<any>({
+      //用户ID
+      id: '',
+      //渠道ID
+      channelId: '',
+      //手机号
+      phone: '',
+      //微信用户
+      name: '',
+      //昵称
+      userName: '',
+      //openId
+      openId: '',
+      //Miami
+      //用户类型
+      type: '',
+      //密码
+      password: '',
+      //用户状态
+      state: '',
+      //用户头像
+      photoPath: '',
+      //是否授权
+      isAuth: '',
+      //渠道名字
+      channelName: '',
+      //邮箱
+      mail: '',
+      //岗位
+      job: '',
+      //公司名称
+      compAddress: '',
+      //公司头像
+      channelAvatar: '',
+      //海报
+      posterBackground: '',
+    })
+    //保存用户信息
+    const saveUserInfo = (val: any) => {
+      userInfo.value = val
+    }
+    //清除用户信息
+    const clearUserInfo = () => {
+      userInfo.value = {}
+    }
     //保存token  token校验时使用
     const saveToken = (val: string) => {
       token.value = val
@@ -31,10 +75,13 @@ export const useMemberStore = defineStore(
     return {
       profile,
       token,
+      userInfo,
       saveToken,
       clearToken,
       setProfile,
       clearProfile,
+      saveUserInfo,
+      clearUserInfo,
     }
   },
   // TODO: 持久化

+ 28 - 0
src/types/home.d.ts

@@ -23,3 +23,31 @@ export type MusicGroup = {
   volume: number
   isClick: boolean
 }
+
+//用户登录需要的参数
+export type LoginParams = {
+  code: string
+  // photoPath?: string
+  // userName?: string
+}
+//用户获取手机号需要的参数
+export type GetPhoneParams = {
+  openId: string
+  code: string
+}
+
+//生成海报
+export type CreatePo = {
+  userId: string
+  title: string
+  effectiveDays: number
+  amount: number
+  times: number
+  background?: string
+}
+
+//根据scene 查询参数的方法
+export type QueryPa = {
+  scene: string
+  userId?: string
+}

+ 6 - 0
src/types/my.d.ts

@@ -0,0 +1,6 @@
+export type UserInfoT = {
+  id: string
+  avatar: string
+  userName: string
+  mail: string
+}

+ 56 - 5
src/utils/http.ts

@@ -1,14 +1,20 @@
 import { useMemberStore } from '@/stores'
 import { Decrypt, Encrypt } from './utils'
+import { userLoginApi } from '@/services/home'
 
 //引入 pinia 。。登录后将信息储存到pinia
 
 // const baseUrl = 'https://pcapi-xiaotuxian-front-devtest.itheima.net'
-const baseUrl = 'https://test.jue-ming.com:8084'
-export const imgUrl = 'https://test.jue-ming.com:8084/file/show?filePath='
+// const baseUrl = 'https://test.jue-ming.com:8084'
+const baseUrl = 'http://10.113.248.3:8086'
+export const imgUrl = 'http://10.113.248.3:8086/file/show?filePath='
+// export const imgUrl = 'https://test.jue-ming.com:8084/file/show?filePath='
 export const mediaUrl = 'https://test.jue-ming.com:8084/file/show/media?filePath='
 // const baseUrl = 'http://10.113.248.3:8080'
 // export const imgUrl = 'http://10.113.248.3:8080/file/show?filePath='
+
+let temp_request: any[] = [],
+  is_freshing = false
 const httpInterceptor = {
   //拦截前触发
   invoke(options: UniApp.RequestOptions) {
@@ -25,7 +31,7 @@ const httpInterceptor = {
     //判断如果请求体里有data//且data不为空
     if ('data' in options) {
       //如果包含data属性
-      options.data = Encrypt(JSON.stringify(options.data))
+      options.data = { data: Encrypt(JSON.stringify(options.data)) }
     }
     console.log(options)
     //添加 token 请求头标识
@@ -54,6 +60,7 @@ interface Data<T> {
 }
 
 export const http = <T>(option: UniApp.RequestOptions) => {
+  let params_ = option
   // console.log(option?.data)
   return new Promise<Data<T>>((resolve, reject) => {
     uni.request({
@@ -65,9 +72,25 @@ export const http = <T>(option: UniApp.RequestOptions) => {
           //访问成功
           // eslint-disable-next-line no-debugger
 
-          // resolve(JSON.parse(Decrypt(res.data)))
-          resolve(res.data as Data<T>)
+          resolve(JSON.parse(Decrypt(res.data)))
+
+          // resolve(res.data as Data<T>)
         } else if (res.statusCode === 401) {
+          //当token过期后弹出确认再次登录的提示框
+          //如果点击确定再次调用登录接口
+          if (!is_freshing) {
+            //调用登录接口
+            refresh()
+          } else {
+            resolve(
+              new Promise((resol) => {
+                temp_request.push(() => {
+                  resol(http(params_))
+                })
+              }),
+            )
+          }
+
           //清理用户信息
           //跳转到登录页
           const memberStore = useMemberStore()
@@ -97,3 +120,31 @@ export const http = <T>(option: UniApp.RequestOptions) => {
     })
   })
 }
+
+const refresh = () => {
+  is_freshing = true
+  uni.login({
+    success: (res) => {
+      if (res.errMsg === 'login:ok') {
+        //调用登录接口
+        //获取到code后
+        loginHttp(res.code)
+      }
+    },
+  })
+}
+
+const loginHttp = async (code: string) => {
+  const res = await userLoginApi({ code: code })
+
+  //登录成功后需要将 is_refresh 状态改为false
+  //然后回调
+  if (res.data) {
+    console.log(res.data)
+  } else {
+    is_freshing = false
+    temp_request.map((cb) => cb())
+    // 清空temp_request
+    temp_request = []
+  }
+}