Browse Source

Merge branch 'dev' of http://1.94.207.143:3000/xyy/xyy-m into dev

qiao 3 months ago
parent
commit
a6be53583b

+ 7 - 0
nuxt.config.ts

@@ -53,6 +53,13 @@ export default defineNuxtConfig({
         },
       ],
       link: [{ rel: "icon", type: "image/x-icon", href: "/favicon.svg" }],
+      // script: [
+      //   {
+      //     src: "//unpkg.com/vconsole@latest/dist/vconsole.min.js",
+      //     type: "text/javascript",
+      //   },
+      //   { innerHTML: "new VConsole()" },
+      // ],
     },
   },
   css: ["@/assets/css/tailwind.css", "./src/assets/iconfont/iconfont.css"],

+ 47 - 48
src/components/CreateNote/HeaderBanner.vue

@@ -29,10 +29,9 @@
       </div>
     </div>
 
-    <!-- style="background-color: transparent" -->
     <van-dialog title="图片剪裁" v-model:show="cropperDialogVisible" width="375">
       <div class="h-full w-full">
-        <img ref="cropperRef" :src="bannerUrl" alt="" />
+        <img ref="cropperRef" :src="cropperImageBase64" alt="" />
         <!-- <vueCropper
           ref="cropperRef"
           :img="cropperImageBase64"
@@ -41,28 +40,31 @@
           centerBox
           fixed
           fixedBox
+          original
           :full="true"
           :fixedNumber="[3.2, 1]"
         ></vueCropper> -->
-        <!-- <vue-cropper
-          v-if="image"
-          :src="image"
-          ref="cropper"
-          :stencil-size="stencilSize"
-          :zoomable="true"
-          :rotatable="true"
-          :background="true"
-          :auto-crop="true"
-          :auto-crop-area="0.8"
-          :guides="true"
-          :center="true"
-          @crop="onCrop"
-        /> -->
       </div>
       <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="cropperDialogVisible = false">取消</el-button>
-          <el-button type="primary" @click="handleCropperOk" :loading="loading">确认</el-button>
+        <div class="flex items-center justify-center space-x-20 pt-10 pb-10">
+          <van-button
+            round
+            plain
+            color="#FF9300"
+            type="primary"
+            @click="cropperDialogVisible = false"
+          >
+            取消
+          </van-button>
+          <van-button
+            round
+            type="primary"
+            @click="handleCropperOk"
+            :loading="loading"
+            color="#FF9300"
+          >
+            确认
+          </van-button>
         </div>
       </template>
     </van-dialog>
@@ -73,30 +75,29 @@
 import { useFileDialog } from '@vueuse/core'
 import icon_image_fill from '~/assets/img/note-create/icon-image-fill.png'
 import image from '~/assets/img/note-create/image.svg'
-// import { VueCropper } from 'vue-cropper'
-// import 'vue-cropper/dist/index.css'
-// import 'https://cdn.jsdelivr.net/npm/vue-cropper@1.0.2/dist/index.css'
+import { VueCropper } from 'vue-cropper'
+import 'vue-cropper/dist/index.css'
 
 const bannerUrl = defineModel('bannerUrl')
 
-const emit = defineEmits(['onSelectImage'])
+// const emit = defineEmits(['onSelectImage'])
 
 const { open, onChange } = useFileDialog({
   accept: '.png,.png,.jpeg,.JPG,Png '
 })
 
 const cropperImageBase64 = ref('')
-const fileList = ref([])
+const fileList = ref({})
 onChange((files) => {
-  console.log(files[0], '4445')
-
   if (!files.length) return
   const reader = new FileReader()
   reader.readAsDataURL(files[0])
   reader.onload = () => {
+    console.log(reader.result, '123')
+
     cropperDialogVisible.value = true
     cropperImageBase64.value = reader.result
-    // bannerUrl.value = reader.result
+    fileList.value = files[0]
   }
 })
 
@@ -110,28 +111,26 @@ const loading = ref(false)
 // async
 
 async function handleCropperOk() {
-  cropperRef.value?.getCropBlob(async (data) => {
-    try {
-      // loading.value = true
-      // 此处需上传图片,保存URL
-      const formData = new FormData()
-      console.log(formData, '121222')
-      console.log(data, '5555')
+  // cropperRef.value.getCropBlob(async (data) => {
+  try {
+    // loading.value = true
+    // 此处需上传图片,保存URL
+    const formData = new FormData()
 
-      formData.append('uploadFile', data)
-      formData.append('asImage', true)
-      formData.append('fieldName', 'travelNotesBanner')
-      const res = await request('/admin/app/tourismProjectTravelNotesWrite/upload', {
-        method: 'post',
-        body: formData
-      })
-      const url = res.data.fileUrl
-      bannerUrl.value = url
-      cropperDialogVisible.value = false
-    } finally {
-      loading.value = false
-    }
-  })
+    formData.append('uploadFile', fileList.value)
+    formData.append('asImage', true)
+    formData.append('fieldName', 'travelNotesBanner')
+    const res = await request('/admin/app/tourismProjectTravelNotesWrite/upload', {
+      method: 'post',
+      body: formData
+    })
+    const url = res.data.fileUrl
+    bannerUrl.value = url
+    cropperDialogVisible.value = false
+  } finally {
+    loading.value = false
+  }
+  // })
 }
 </script>
 

+ 18 - 5
src/components/NavigationBar/LeftMenu.vue

@@ -12,8 +12,8 @@
       <span class="text-black-6 text-base">登录</span>
     </NuxtLink>
 
-    <NuxtLink
-      to="/profile"
+    <div
+      @click="handleToProfile"
       v-else-if="token"
       class="flex items-center space-x-15"
     >
@@ -25,13 +25,17 @@
         class="shrink-0"
       ></van-image>
       <div class="flex-1 flex flex-col">
-        <div class="text-black-3 text-base">{{ userInfo.showName }}</div>
+        <div class="text-black-3 text-base break-all">
+          {{ userInfo.showName }}
+        </div>
         <div v-if="userInfo.personalSign" class="text-black-6 text-sm">
           <span class="text-black-6">个性签名:</span>
-          <span class="text-black-3">{{ userInfo.personalSign }}</span>
+          <span class="text-black-3 break-all">{{
+            userInfo.personalSign
+          }}</span>
         </div>
       </div>
-    </NuxtLink>
+    </div>
 
     <div class="flex flex-col mt-20 divide-y flex-1 overflow-scroll">
       <div
@@ -69,6 +73,8 @@ import menu_profile from "@/assets/img/navbar/menu_profile.png";
 
 const visible = defineModel("visible");
 
+const route = useRoute();
+
 const authStore = useAuthStore();
 const { token } = storeToRefs(authStore);
 
@@ -154,6 +160,13 @@ function handleClickMenu(item) {
   });
 }
 
+function handleToProfile() {
+  visible.value = false;
+  navigateTo({
+    path: "/profile",
+  });
+}
+
 function handleLogout() {
   try {
     request("/website/web/doLogout", { method: "post" });

+ 0 - 1
src/pages/note-create/index.client.vue

@@ -443,7 +443,6 @@ const noteJson = reactive(defaultNoteJson)
 watch(noteJson, () => {}, { deep: true })
 
 const id = useRouteQuery('id')
-console.log(noteJson.projectTitle, 'projectTitle')
 
 watch(
   id,

+ 3 - 3
src/pages/profile/index.vue

@@ -3,7 +3,7 @@
     <div
       class="h-250 relative w-full bg-[url('~/assets/img/profile/profile_banner.png')] bg-no-repeat bg-cover"
     >
-      <div class="absolute left-20 bottom-10">
+      <div class="absolute left-20 bottom-10 right-20">
         <NuxtLink to="/profile/userInfo" class="flex items-center space-x-10">
           <van-image
             :src="userInfo.headImageUrl"
@@ -12,11 +12,11 @@
             fit="cover"
             radius="37.5px"
           />
-          <span class="text-2xl font-semibold text-white">
+          <span class="text-2xl break-all font-semibold text-white">
             {{ userInfo.showName }}</span
           >
         </NuxtLink>
-        <div class="text-xl text-white font-semibold mt-15">
+        <div class="text-xl break-all text-white font-semibold mt-15">
           个性签名:{{ userInfo.personalSign || "暂未填写" }}
         </div>
       </div>

+ 47 - 43
src/pages/profile/userInfo.vue

@@ -4,24 +4,16 @@
       <van-cell-group inset>
         <van-field name="uploader" label="头像">
           <template #input>
-            <div @click="handleChangeAvatar">
-              <van-image
-                v-if="userInfo.headImageUrl"
-                :src="userInfo.headImageUrl"
-                width="75px"
-                height="75px"
-                radius="37.5px"
-              />
-              <div
-                v-else
-                class="w-75 h-75 rounded-full bg-black-d flex items-center justify-center"
-              >
-                <span
-                  class="iconfont icon-profile text-black-6"
-                  style="font-size: 36px"
-                ></span>
-              </div>
-            </div>
+            <van-uploader
+              style="--van-uploader-border-radius: 40px"
+              :after-read="afterRead"
+              v-model="fileList"
+              :max-count="1"
+              :deletable="false"
+              :multiple="false"
+              accept="image/*"
+              reupload
+            />
           </template>
         </van-field>
         <van-field
@@ -29,6 +21,7 @@
           name="昵称"
           label="昵称"
           placeholder="昵称"
+          maxlength="20"
           :rules="[{ required: true, message: '请填写昵称' }]"
         />
         <van-field name="radio" label="性别">
@@ -44,18 +37,27 @@
           name="邮箱"
           label="邮箱"
           placeholder="邮箱"
-          :rules="[{ required: true, message: '请填写邮箱' }]"
+          maxlength="100"
+          :rules="[
+            {
+              required: true,
+              validator: validatorEmail,
+              message: '请填写正确的邮箱',
+            },
+          ]"
         />
         <van-field
           v-model="userInfo.job"
           name="职业"
           label="职业"
           placeholder="职业"
+          maxlength="100"
         />
         <van-field
           v-model="userInfo.address"
           name="居住地"
           label="居住地"
+          maxlength="100"
           placeholder="居住地"
         />
         <van-field
@@ -87,6 +89,8 @@
 const userInfoStore = useUserInfoStore();
 const { userInfo } = storeToRefs(userInfoStore);
 
+const fileList = ref([]);
+
 const form = reactive({
   showName: null,
   email: null,
@@ -98,6 +102,27 @@ const form = reactive({
   personalSign: null,
 });
 
+const validatorEmail = (val) =>
+  /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
+    val
+  );
+
+async function afterRead(file) {
+  console.log(file);
+  const formData = new FormData();
+  formData.append("uploadFile", file.file);
+  formData.append("asImage", true);
+  formData.append("fieldName", "headImageUrl");
+  try {
+    const { data } = await request("/website/tourism/user/upload", {
+      method: "post",
+      body: formData,
+    });
+    form.headImageUrl = data.fileUrl;
+    userInfoStore.getUserInfo();
+  } catch (error) {}
+}
+
 watch(
   userInfo,
   () => {
@@ -105,6 +130,9 @@ watch(
     form.email = userInfo.value.email;
     form.sex = userInfo.value.sex;
     form.headImageUrl = userInfo.value.headImageUrl;
+    fileList.value[0] = {
+      url: userInfo.value.headImageUrl,
+    };
     form.address = userInfo.value.address;
     form.job = userInfo.value.job;
     form.personalSign = userInfo.value.personalSign;
@@ -119,30 +147,6 @@ onMounted(() => {
   userInfoStore.getUserInfo();
 });
 
-const { open, onChange } = useFileDialog({
-  accept: ".png,.png,.jpeg,.JPG,Png ",
-});
-
-function handleChangeAvatar() {
-  open();
-}
-
-onChange(async (files) => {
-  if (!files.length) return;
-  const formData = new FormData();
-  formData.append("uploadFile", files[0]);
-  formData.append("asImage", true);
-  formData.append("fieldName", "headImageUrl");
-  try {
-    const { data } = await request("/website/tourism/user/upload", {
-      method: "post",
-      body: formData,
-    });
-    form.headImageUrl = data.fileUrl;
-    userInfoStore.getUserInfo();
-  } catch (error) {}
-});
-
 async function handleSubmit() {
   try {
     await request("/website/tourism/user/update", {

+ 4 - 2
src/pages/t/[id].client.vue

@@ -116,12 +116,14 @@ function handleSubmitInfo() {
       if (data === 1) {
         showDialog({
           title: "预定成功",
-          message: "恭喜预定成功我们会尽快和您取得联系",
+          message:
+            "因为旅游预定涉及较多的环节,我们需要线下和您沟通,我们会尽快与你联系并为您提供最真诚的服务。",
         }).then(() => {});
       } else if (data === 2) {
         showDialog({
           title: "您已预定",
-          message: "我们会尽快和您取得联系",
+          message:
+            "因为旅游预定涉及较多的环节,我们需要线下和您沟通,我们会尽快与你联系并为您提供最真诚的服务。",
         }).then(() => {
           // on close
         });