yangg 3 місяців тому
батько
коміт
42433b56b1

+ 1 - 0
components/voice-check-modal.vue

@@ -0,0 +1 @@
+ 

+ 7 - 0
pages.json

@@ -127,6 +127,13 @@
 			{
 				"navigationBarTitleText" : ""
 			}
+		},
+		{
+			"path": "pages/posture-guide/posture-guide",
+			"style": {
+				"navigationBarTitleText": "体态评估指导",
+				"navigationStyle": "default"
+			}
 		}
 	],
 	

+ 151 - 0
pages/components/voice-check-modal.vue

@@ -0,0 +1,151 @@
+<template>
+  <view class="modal" v-if="visible">
+    <view class="modal-content">
+      <view class="modal-title">麦克风检测</view>
+      <view class="modal-text">请朗读下面的文字</view>
+      
+      <!-- 语音波形动画 -->
+      <view class="wave-container" v-if="isRecording">
+        <view class="wave-bar" v-for="(item, index) in waveData" :key="index" 
+              :style="{ height: item + 'rpx' }"></view>
+      </view>
+      
+      <!-- 待朗读文字 -->
+      <view class="read-text">成为奇才,就是现在,我们开始吧。</view>
+      
+      <!-- 按钮 -->
+      <button class="confirm-btn" @tap="handleConfirm">
+        {{ isRecording ? '读完了' : '开始' }}
+      </button>
+    </view>
+  </view>
+</template>
+
+<script>
+const recorderManager = uni.getRecorderManager();
+
+export default {
+  name: 'VoiceCheckModal',
+  props: {
+    visible: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      isRecording: false,
+      waveData: Array(20).fill(20), // 初始波形数据
+      waveTimer: null
+    }
+  },
+  methods: {
+    // 开始录音
+    startRecording() {
+      this.isRecording = true;
+      recorderManager.start({
+        duration: 10000,
+        sampleRate: 16000,
+        numberOfChannels: 1,
+        encodeBitRate: 48000,
+        format: 'wav'
+      });
+      
+      // 模拟波形动画
+      this.waveTimer = setInterval(() => {
+        this.waveData = this.waveData.map(() => Math.random() * 40 + 20);
+      }, 100);
+    },
+    
+    // 停止录音
+    stopRecording() {
+      this.isRecording = false;
+      recorderManager.stop();
+      clearInterval(this.waveTimer);
+      this.waveData = Array(20).fill(20);
+    },
+    
+    // 处理确认按钮点击
+    handleConfirm() {
+      if (!this.isRecording) {
+        this.startRecording();
+      } else {
+        this.stopRecording();
+        this.$emit('complete');
+      }
+    }
+  },
+  beforeDestroy() {
+    clearInterval(this.waveTimer);
+  }
+}
+</script>
+
+<style scoped>
+.modal {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(0, 0, 0, 0.6);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  z-index: 999;
+}
+
+.modal-content {
+  width: 80%;
+  background: #fff;
+  border-radius: 20rpx;
+  padding: 40rpx;
+  text-align: center;
+}
+
+.modal-title {
+  font-size: 32rpx;
+  font-weight: bold;
+  margin-bottom: 20rpx;
+}
+
+.modal-text {
+  font-size: 28rpx;
+  color: #666;
+  margin-bottom: 30rpx;
+}
+
+.wave-container {
+  height: 160rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  gap: 6rpx;
+  margin: 30rpx 0;
+}
+
+.wave-bar {
+  width: 8rpx;
+  background: #0039b3;
+  border-radius: 4rpx;
+  transition: height 0.1s ease;
+}
+
+.read-text {
+  background: #f5f5f5;
+  padding: 30rpx;
+  border-radius: 10rpx;
+  font-size: 30rpx;
+  margin: 30rpx 0;
+}
+
+.confirm-btn {
+  width: 80%;
+  height: 80rpx;
+  line-height: 80rpx;
+  background: #0039b3;
+  color: #fff;
+  border-radius: 40rpx;
+  margin-top: 30rpx;
+}
+</style>

+ 23 - 2
pages/interview-notice/interview-notice.vue

@@ -68,16 +68,28 @@
       <text class="agreement-text">我同意并知晓</text>
     </view>
     
+    <!-- 添加语音检测组件 -->
+    <voice-check-modal 
+      :visible="showVoiceCheck"
+      @complete="onVoiceCheckComplete"
+    />
+    
     <!-- 底部按钮 -->
     <button class="next-btn" :disabled="!isAgreed" @click="startInterview">下一步</button>
   </view>
 </template>
 
 <script>
+import VoiceCheckModal from '../components/voice-check-modal.vue'
+
 export default {
+  components: {
+    VoiceCheckModal
+  },
   data() {
     return {
-      isAgreed: false
+      isAgreed: false,
+      showVoiceCheck: false
     }
   },
   methods: {
@@ -93,8 +105,17 @@ export default {
         return;
       }
       
+      // 显示语音检测弹窗
+      this.showVoiceCheck = true;
+    },
+    
+    onVoiceCheckComplete() {
+      // 关闭语音检测弹窗
+      this.showVoiceCheck = false;
+      
+      // 跳转到下一个页面
       uni.navigateTo({
-        url: '/pages/preview/preview',///pages/face-photo/face-photo
+        url: '/pages/preview/preview',
         fail: (err) => {
           console.error('页面跳转失败:', err);
           uni.showToast({

+ 1 - 1
pages/interview-question/interview-question.vue

@@ -2282,7 +2282,7 @@ export default {
           
           // 如果跳转失败,尝试跳转到其他页面
           uni.navigateTo({
-            url: '/pages/interview/interview',
+            url: '/pages/posture-guide/posture-guide',
             fail: (err2) => {
               console.error('备用跳转也失败:', err2);
               

+ 220 - 0
pages/posture-guide/posture-guide.vue

@@ -0,0 +1,220 @@
+<template>
+  <view class="posture-guide">
+    <view class="guide-content">
+      <view class="guide-title">体态评估环节</view>
+      <view class="guide-subtitle">请仔细阅读下方说明,完整展示手臂</view>
+      
+      <!-- 添加轮播图组件 -->
+      <swiper 
+        class="guide-swiper"
+        :indicator-dots="true"
+        indicator-color="rgba(0, 0, 0, .3)"
+        indicator-active-color="#000000"
+        :autoplay="false"
+        @change="handleSwiperChange"
+      >
+        <swiper-item v-for="(item, index) in guideImages" :key="index">
+          <view class="swiper-item">
+            <image :src="item.url" mode="aspectFit" class="guide-image"></image>
+            <view class="image-description">{{item.description}}</view>
+          </view>
+        </swiper-item>
+      </swiper>
+      
+      <!-- <view class="guide-instructions">
+        <text>{{currentInstruction}}</text>
+      </view> -->
+      
+      <!-- 按钮根据是否是最后一张图片来决定是否禁用 -->
+      <button 
+        class="confirm-button" 
+        :class="{'button-disabled': !isLastSlide}"
+        :disabled="!isLastSlide"
+        @click="handleConfirm"
+      >
+        {{isLastSlide ? '我知道了,开始采集' : '请查看完所有说明'}}
+      </button>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      currentIndex: 0,
+      isLastSlide: false,
+      guideImages: [
+        {
+          url: 'https://data.qicai321.com/minlong/85fbafbd-1b80-48cd-bcd6-fc4911e9ff54.jpg',
+          description: '左手手掌'
+        },
+        {
+          url: 'https://data.qicai321.com/minlong/17d141e0-8f99-4a54-a534-f6b954c600f8.png',
+          description: '左手手背'
+        },
+        {
+          url: 'https://data.qicai321.com/minlong/5c7d7d6f-5e14-4cd6-bb9f-11509473a8bb.png',
+          description: '左手握拳'
+        },
+        {
+          url: 'https://data.qicai321.com/minlong/148eea00-21b4-49e1-a3b6-712fff08a5a8.png',
+          description: '右手手掌'
+        },
+        {
+          url: 'https://data.qicai321.com/minlong/c67c303e-91c0-4e79-8e82-84096435481f.png',
+          description: '右手手背'
+        },
+        {
+          url: 'https://data.qicai321.com/minlong/5a093f70-d397-4a36-9539-a8b4d11e0a13.png',
+          description: '右手握拳'
+        },
+      ],
+      instructions: [
+        '第1步:请按图示展示左手手掌',
+        '第2步:请按图示展示左手手背',
+        '第3步:请按图示展示左手握拳',
+        '第4步:请按图示展示右手手掌',
+        '第5步:请按图示展示右手手背',
+        '第6步:请按图示展示右手握拳'
+      ]
+    }
+  },
+  
+  computed: {
+    currentInstruction() {
+      return this.instructions[this.currentIndex];
+    }
+  },
+  
+  methods: {
+    handleSwiperChange(e) {
+      this.currentIndex = e.detail.current;
+      // 判断是否是最后一张图片
+      this.isLastSlide = this.currentIndex === this.guideImages.length - 1;
+    },
+    
+    handleConfirm() {
+      if (this.isLastSlide) {
+        uni.navigateTo({
+          url: '/pages/interview/interview'
+        });
+      } else {
+        uni.showToast({
+          title: '请查看完所有说明',
+          icon: 'none'
+        });
+      }
+    }
+  }
+}
+</script>
+
+<style>
+.posture-guide {
+  min-height: 100vh;
+  background-color: #fff;
+  padding: 30rpx;
+}
+
+.guide-content {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+.guide-title {
+  font-size: 36rpx;
+  font-weight: bold;
+  margin-bottom: 20rpx;
+  color: #333;
+}
+
+.guide-subtitle {
+  font-size: 28rpx;
+  color: #666;
+  margin-bottom: 40rpx;
+}
+
+/* 轮播图样式 */
+.guide-swiper {
+  width: 100%;
+  height: 800rpx;
+  margin: 30rpx 0;
+  position: relative;
+  padding-bottom: 40rpx; /* 添加底部padding为指示点留出空间 */
+}
+
+.swiper-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  height: 100%;
+}
+
+.guide-image {
+  width: 90%;
+  height: 600rpx;
+  object-fit: contain;
+}
+
+.image-description {
+  margin-top: 20rpx;
+  font-size: 28rpx;
+  color: #333;
+  text-align: center;
+}
+
+.guide-instructions {
+  padding: 20rpx;
+  margin: 30rpx 0;
+  text-align: center;
+  font-size: 28rpx;
+  color: #666;
+  background-color: #f8f8f8;
+  border-radius: 10rpx;
+  width: 90%;
+  margin-top: 60rpx;
+}
+
+.confirm-button {
+  width: 80%;
+  height: 88rpx;
+  line-height: 88rpx;
+  background-color: #0039b3;
+  color: #fff;
+  border-radius: 44rpx;
+  font-size: 32rpx;
+  margin-top: 40rpx;
+}
+
+/* 禁用状态的按钮样式 */
+.button-disabled {
+  background-color: #cccccc;
+  opacity: 0.8;
+}
+
+/* 修改指示点容器样式 */
+:deep(.uni-swiper-dots) {
+  display: flex;
+  justify-content: center;
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
+}
+
+/* 修改指示点样式 */
+:deep(.uni-swiper-dot) {
+  width: 16rpx !important;
+  height: 16rpx !important;
+  margin: 0 8rpx !important;
+  border-radius: 50%;
+  background: rgba(0, 0, 0, 0.3) !important;
+}
+
+:deep(.uni-swiper-dot-active) {
+  background: #000000 !important;
+}
+</style> 

+ 1 - 0
unpackage/dist/dev/mp-weixin/app.js

@@ -22,6 +22,7 @@ if (!Math) {
   "./pages/job-detail/job-detail.js";
   "./pages/followUp/followUp.js";
   "./pages/uploadResume/uploadResume.js";
+  "./pages/posture-guide/posture-guide.js";
 }
 const _sfc_main = {
   onLaunch: function() {

+ 2 - 1
unpackage/dist/dev/mp-weixin/app.json

@@ -18,7 +18,8 @@
     "pages/Personal/Personal",
     "pages/job-detail/job-detail",
     "pages/followUp/followUp",
-    "pages/uploadResume/uploadResume"
+    "pages/uploadResume/uploadResume",
+    "pages/posture-guide/posture-guide"
   ],
   "window": {
     "navigationBarTextStyle": "black",

+ 74 - 0
unpackage/dist/dev/mp-weixin/pages/components/voice-check-modal.js

@@ -0,0 +1,74 @@
+"use strict";
+const common_vendor = require("../../common/vendor.js");
+const recorderManager = common_vendor.index.getRecorderManager();
+const _sfc_main = {
+  name: "VoiceCheckModal",
+  props: {
+    visible: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      isRecording: false,
+      waveData: Array(20).fill(20),
+      // 初始波形数据
+      waveTimer: null
+    };
+  },
+  methods: {
+    // 开始录音
+    startRecording() {
+      this.isRecording = true;
+      recorderManager.start({
+        duration: 1e4,
+        sampleRate: 16e3,
+        numberOfChannels: 1,
+        encodeBitRate: 48e3,
+        format: "wav"
+      });
+      this.waveTimer = setInterval(() => {
+        this.waveData = this.waveData.map(() => Math.random() * 40 + 20);
+      }, 100);
+    },
+    // 停止录音
+    stopRecording() {
+      this.isRecording = false;
+      recorderManager.stop();
+      clearInterval(this.waveTimer);
+      this.waveData = Array(20).fill(20);
+    },
+    // 处理确认按钮点击
+    handleConfirm() {
+      if (!this.isRecording) {
+        this.startRecording();
+      } else {
+        this.stopRecording();
+        this.$emit("complete");
+      }
+    }
+  },
+  beforeDestroy() {
+    clearInterval(this.waveTimer);
+  }
+};
+function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
+  return common_vendor.e({
+    a: $props.visible
+  }, $props.visible ? common_vendor.e({
+    b: $data.isRecording
+  }, $data.isRecording ? {
+    c: common_vendor.f($data.waveData, (item, index, i0) => {
+      return {
+        a: index,
+        b: item + "rpx"
+      };
+    })
+  } : {}, {
+    d: common_vendor.t($data.isRecording ? "读完了" : "开始"),
+    e: common_vendor.o((...args) => $options.handleConfirm && $options.handleConfirm(...args))
+  }) : {});
+}
+const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-ce199c44"]]);
+wx.createComponent(Component);

+ 4 - 0
unpackage/dist/dev/mp-weixin/pages/components/voice-check-modal.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 1 - 0
unpackage/dist/dev/mp-weixin/pages/components/voice-check-modal.wxml

@@ -0,0 +1 @@
+<view wx:if="{{a}}" class="modal data-v-ce199c44"><view class="modal-content data-v-ce199c44"><view class="modal-title data-v-ce199c44">麦克风检测</view><view class="modal-text data-v-ce199c44">请朗读下面的文字</view><view wx:if="{{b}}" class="wave-container data-v-ce199c44"><view wx:for="{{c}}" wx:for-item="item" wx:key="a" class="wave-bar data-v-ce199c44" style="{{'height:' + item.b}}"></view></view><view class="read-text data-v-ce199c44">成为奇才,就是现在,我们开始吧。</view><button class="confirm-btn data-v-ce199c44" bindtap="{{e}}">{{d}}</button></view></view>

+ 60 - 0
unpackage/dist/dev/mp-weixin/pages/components/voice-check-modal.wxss

@@ -0,0 +1,60 @@
+
+.modal.data-v-ce199c44 {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(0, 0, 0, 0.6);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  z-index: 999;
+}
+.modal-content.data-v-ce199c44 {
+  width: 80%;
+  background: #fff;
+  border-radius: 20rpx;
+  padding: 40rpx;
+  text-align: center;
+}
+.modal-title.data-v-ce199c44 {
+  font-size: 32rpx;
+  font-weight: bold;
+  margin-bottom: 20rpx;
+}
+.modal-text.data-v-ce199c44 {
+  font-size: 28rpx;
+  color: #666;
+  margin-bottom: 30rpx;
+}
+.wave-container.data-v-ce199c44 {
+  height: 160rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  gap: 6rpx;
+  margin: 30rpx 0;
+}
+.wave-bar.data-v-ce199c44 {
+  width: 8rpx;
+  background: #0039b3;
+  border-radius: 4rpx;
+  transition: height 0.1s ease;
+}
+.read-text.data-v-ce199c44 {
+  background: #f5f5f5;
+  padding: 30rpx;
+  border-radius: 10rpx;
+  font-size: 30rpx;
+  margin: 30rpx 0;
+}
+.confirm-btn.data-v-ce199c44 {
+  width: 80%;
+  height: 80rpx;
+  line-height: 80rpx;
+  background: #0039b3;
+  color: #fff;
+  border-radius: 40rpx;
+  margin-top: 30rpx;
+}

+ 20 - 4
unpackage/dist/dev/mp-weixin/pages/interview-notice/interview-notice.js

@@ -1,9 +1,14 @@
 "use strict";
 const common_vendor = require("../../common/vendor.js");
+const VoiceCheckModal = () => "../components/voice-check-modal.js";
 const _sfc_main = {
+  components: {
+    VoiceCheckModal
+  },
   data() {
     return {
-      isAgreed: false
+      isAgreed: false,
+      showVoiceCheck: false
     };
   },
   methods: {
@@ -18,9 +23,12 @@ const _sfc_main = {
         });
         return;
       }
+      this.showVoiceCheck = true;
+    },
+    onVoiceCheckComplete() {
+      this.showVoiceCheck = false;
       common_vendor.index.navigateTo({
         url: "/pages/preview/preview",
-        ///pages/face-photo/face-photo
         fail: (err) => {
           console.error("页面跳转失败:", err);
           common_vendor.index.showToast({
@@ -32,12 +40,20 @@ const _sfc_main = {
     }
   }
 };
+if (!Array) {
+  const _component_voice_check_modal = common_vendor.resolveComponent("voice-check-modal");
+  _component_voice_check_modal();
+}
 function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
   return {
     a: $data.isAgreed,
     b: common_vendor.o((...args) => $options.toggleAgreement && $options.toggleAgreement(...args)),
-    c: !$data.isAgreed,
-    d: common_vendor.o((...args) => $options.startInterview && $options.startInterview(...args))
+    c: common_vendor.o($options.onVoiceCheckComplete),
+    d: common_vendor.p({
+      visible: $data.showVoiceCheck
+    }),
+    e: !$data.isAgreed,
+    f: common_vendor.o((...args) => $options.startInterview && $options.startInterview(...args))
   };
 }
 const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);

+ 3 - 1
unpackage/dist/dev/mp-weixin/pages/interview-notice/interview-notice.json

@@ -1,5 +1,7 @@
 {
   "navigationBarTitleText": "面试注意事项",
   "navigationStyle": "default",
-  "usingComponents": {}
+  "usingComponents": {
+    "voice-check-modal": "../components/voice-check-modal"
+  }
 }

+ 1 - 1
unpackage/dist/dev/mp-weixin/pages/interview-notice/interview-notice.wxml

@@ -1 +1 @@
-<view class="notice-container"><view class="notice-title">面试注意事项</view><view class="notice-subtitle">为了保障面试顺利进行,请注意以下事项</view><view class="notice-grid"><view class="notice-item light"><view class="icon-container"><text class="iconfont">☀</text></view><text class="item-text">保持光线良好、干净背景、安静不受打扰</text></view><view class="notice-item smile"><view class="icon-container"><text class="iconfont">☺</text></view><text class="item-text">保持微笑、声音洪亮、正面直视摄像头</text></view><view class="notice-item headphone"><view class="icon-container"><text class="iconfont">🎧</text></view><text class="item-text">保持声音回音接收正常、建议使用耳机</text></view><view class="notice-item wifi"><view class="icon-container"><text class="iconfont">📶</text></view><text class="item-text">保持网络通畅、面试期间勿断出</text></view><view class="notice-item forbidden"><view class="icon-container"><text class="iconfont">✖</text></view><text class="item-text">请勿人脸离开屏幕</text></view><view class="notice-item forbidden"><view class="icon-container"><text class="iconfont">✖</text></view><text class="item-text">请勿录屏、截屏</text></view></view><view class="warning-tip"> * 建议开启免提模式,避免采用\短信等打断面试 </view><view class="agreement"><radio checked="{{a}}" bindtap="{{b}}"/><text class="agreement-text">我同意并知晓</text></view><button class="next-btn" disabled="{{c}}" bindtap="{{d}}">下一步</button></view>
+<view class="notice-container"><view class="notice-title">面试注意事项</view><view class="notice-subtitle">为了保障面试顺利进行,请注意以下事项</view><view class="notice-grid"><view class="notice-item light"><view class="icon-container"><text class="iconfont">☀</text></view><text class="item-text">保持光线良好、干净背景、安静不受打扰</text></view><view class="notice-item smile"><view class="icon-container"><text class="iconfont">☺</text></view><text class="item-text">保持微笑、声音洪亮、正面直视摄像头</text></view><view class="notice-item headphone"><view class="icon-container"><text class="iconfont">🎧</text></view><text class="item-text">保持声音回音接收正常、建议使用耳机</text></view><view class="notice-item wifi"><view class="icon-container"><text class="iconfont">📶</text></view><text class="item-text">保持网络通畅、面试期间勿断出</text></view><view class="notice-item forbidden"><view class="icon-container"><text class="iconfont">✖</text></view><text class="item-text">请勿人脸离开屏幕</text></view><view class="notice-item forbidden"><view class="icon-container"><text class="iconfont">✖</text></view><text class="item-text">请勿录屏、截屏</text></view></view><view class="warning-tip"> * 建议开启免提模式,避免采用\短信等打断面试 </view><view class="agreement"><radio checked="{{a}}" bindtap="{{b}}"/><text class="agreement-text">我同意并知晓</text></view><voice-check-modal wx:if="{{d}}" bindcomplete="{{c}}" u-i="389291d2-0" bind:__l="__l" u-p="{{d}}"/><button class="next-btn" disabled="{{e}}" bindtap="{{f}}">下一步</button></view>

+ 1 - 1
unpackage/dist/dev/mp-weixin/pages/interview-question/interview-question.js

@@ -1503,7 +1503,7 @@ const _sfc_main = {
         fail: (err) => {
           console.error("跳转失败:", err);
           common_vendor.index.navigateTo({
-            url: "/pages/interview/interview",
+            url: "/pages/posture-guide/posture-guide",
             fail: (err2) => {
               console.error("备用跳转也失败:", err2);
               common_vendor.index.navigateBack({

+ 85 - 0
unpackage/dist/dev/mp-weixin/pages/posture-guide/posture-guide.js

@@ -0,0 +1,85 @@
+"use strict";
+const common_vendor = require("../../common/vendor.js");
+const _sfc_main = {
+  data() {
+    return {
+      currentIndex: 0,
+      isLastSlide: false,
+      guideImages: [
+        {
+          url: "https://data.qicai321.com/minlong/85fbafbd-1b80-48cd-bcd6-fc4911e9ff54.jpg",
+          description: "左手手掌"
+        },
+        {
+          url: "https://data.qicai321.com/minlong/17d141e0-8f99-4a54-a534-f6b954c600f8.png",
+          description: "左手手背"
+        },
+        {
+          url: "https://data.qicai321.com/minlong/5c7d7d6f-5e14-4cd6-bb9f-11509473a8bb.png",
+          description: "左手握拳"
+        },
+        {
+          url: "https://data.qicai321.com/minlong/148eea00-21b4-49e1-a3b6-712fff08a5a8.png",
+          description: "右手手掌"
+        },
+        {
+          url: "https://data.qicai321.com/minlong/c67c303e-91c0-4e79-8e82-84096435481f.png",
+          description: "右手手背"
+        },
+        {
+          url: "https://data.qicai321.com/minlong/5a093f70-d397-4a36-9539-a8b4d11e0a13.png",
+          description: "右手握拳"
+        }
+      ],
+      instructions: [
+        "第1步:请按图示展示左手手掌",
+        "第2步:请按图示展示左手手背",
+        "第3步:请按图示展示左手握拳",
+        "第4步:请按图示展示右手手掌",
+        "第5步:请按图示展示右手手背",
+        "第6步:请按图示展示右手握拳"
+      ]
+    };
+  },
+  computed: {
+    currentInstruction() {
+      return this.instructions[this.currentIndex];
+    }
+  },
+  methods: {
+    handleSwiperChange(e) {
+      this.currentIndex = e.detail.current;
+      this.isLastSlide = this.currentIndex === this.guideImages.length - 1;
+    },
+    handleConfirm() {
+      if (this.isLastSlide) {
+        common_vendor.index.navigateTo({
+          url: "/pages/interview/interview"
+        });
+      } else {
+        common_vendor.index.showToast({
+          title: "请查看完所有说明",
+          icon: "none"
+        });
+      }
+    }
+  }
+};
+function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
+  return {
+    a: common_vendor.f($data.guideImages, (item, index, i0) => {
+      return {
+        a: item.url,
+        b: common_vendor.t(item.description),
+        c: index
+      };
+    }),
+    b: common_vendor.o((...args) => $options.handleSwiperChange && $options.handleSwiperChange(...args)),
+    c: common_vendor.t($data.isLastSlide ? "我知道了,开始采集" : "请查看完所有说明"),
+    d: !$data.isLastSlide ? 1 : "",
+    e: !$data.isLastSlide,
+    f: common_vendor.o((...args) => $options.handleConfirm && $options.handleConfirm(...args))
+  };
+}
+const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
+wx.createPage(MiniProgramPage);

+ 5 - 0
unpackage/dist/dev/mp-weixin/pages/posture-guide/posture-guide.json

@@ -0,0 +1,5 @@
+{
+  "navigationBarTitleText": "体态评估指导",
+  "navigationStyle": "default",
+  "usingComponents": {}
+}

+ 1 - 0
unpackage/dist/dev/mp-weixin/pages/posture-guide/posture-guide.wxml

@@ -0,0 +1 @@
+<view class="posture-guide"><view class="guide-content"><view class="guide-title">体态评估环节</view><view class="guide-subtitle">请仔细阅读下方说明,完整展示手臂</view><swiper class="guide-swiper" indicator-dots="{{true}}" indicator-color="rgba(0, 0, 0, .3)" indicator-active-color="#000000" autoplay="{{false}}" bindchange="{{b}}"><swiper-item wx:for="{{a}}" wx:for-item="item" wx:key="c"><view class="swiper-item"><image src="{{item.a}}" mode="aspectFit" class="guide-image"></image><view class="image-description">{{item.b}}</view></view></swiper-item></swiper><button class="{{['confirm-button', d && 'button-disabled']}}" disabled="{{e}}" bindtap="{{f}}">{{c}}</button></view></view>

+ 98 - 0
unpackage/dist/dev/mp-weixin/pages/posture-guide/posture-guide.wxss

@@ -0,0 +1,98 @@
+
+.posture-guide {
+  min-height: 100vh;
+  background-color: #fff;
+  padding: 30rpx;
+}
+.guide-content {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+.guide-title {
+  font-size: 36rpx;
+  font-weight: bold;
+  margin-bottom: 20rpx;
+  color: #333;
+}
+.guide-subtitle {
+  font-size: 28rpx;
+  color: #666;
+  margin-bottom: 40rpx;
+}
+
+/* 轮播图样式 */
+.guide-swiper {
+  width: 100%;
+  height: 800rpx;
+  margin: 30rpx 0;
+  position: relative;
+  padding-bottom: 40rpx; /* 添加底部padding为指示点留出空间 */
+}
+.swiper-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  height: 100%;
+}
+.guide-image {
+  width: 90%;
+  height: 600rpx;
+  object-fit: contain;
+}
+.image-description {
+  margin-top: 20rpx;
+  font-size: 28rpx;
+  color: #333;
+  text-align: center;
+}
+.guide-instructions {
+  padding: 20rpx;
+  margin: 30rpx 0;
+  text-align: center;
+  font-size: 28rpx;
+  color: #666;
+  background-color: #f8f8f8;
+  border-radius: 10rpx;
+  width: 90%;
+  margin-top: 60rpx;
+}
+.confirm-button {
+  width: 80%;
+  height: 88rpx;
+  line-height: 88rpx;
+  background-color: #0039b3;
+  color: #fff;
+  border-radius: 44rpx;
+  font-size: 32rpx;
+  margin-top: 40rpx;
+}
+
+/* 禁用状态的按钮样式 */
+.button-disabled {
+  background-color: #cccccc;
+  opacity: 0.8;
+}
+
+/* 修改指示点容器样式 */
+ .uni-swiper-dots {
+  display: flex;
+  justify-content: center;
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
+}
+
+/* 修改指示点样式 */
+ .uni-swiper-dot {
+  width: 16rpx !important;
+  height: 16rpx !important;
+  margin: 0 8rpx !important;
+  border-radius: 50%;
+  background: rgba(0, 0, 0, 0.3) !important;
+}
+ .uni-swiper-dot-active {
+  background: #000000 !important;
+}

+ 14 - 0
unpackage/dist/dev/mp-weixin/project.private.config.json

@@ -7,6 +7,20 @@
   "condition": {
     "miniprogram": {
       "list": [
+        {
+          "name": "pages/posture-guide/posture-guide",
+          "pathName": "pages/posture-guide/posture-guide",
+          "query": "",
+          "launchMode": "default",
+          "scene": null
+        },
+        {
+          "name": "pages/interview-notice/interview-notice",
+          "pathName": "pages/interview-notice/interview-notice",
+          "query": "",
+          "launchMode": "default",
+          "scene": null
+        },
         {
           "name": "pages/uploadResume/uploadResume",
           "pathName": "pages/uploadResume/uploadResume",