liujiaxin hace 12 horas
padre
commit
8da2735d15

+ 41 - 14
App.vue

@@ -1,13 +1,11 @@
 <script>
-	import Vue from 'vue'
-	// import TIM from 'tim-wx-sdk';
-	// import COS from 'cos-wx-sdk-v5';
-	export default {
-		globalData: {  
-			// confirm订单参数
-			confirmParam: []
-		},
-		onLaunch: function() {
+import Vue from 'vue'
+export default {
+	globalData: {  
+		// confirm订单参数
+		confirmParam: []
+	},
+	onLaunch: function() {
 			// uni.$TUIKit = TIM.create({
 			// 	SDKAppID: 1400693126
 			// });
@@ -28,8 +26,9 @@
 			// console.log('IM')
 		},
 		onShow: function () {
-		    console.log('App Show')
-		    uni.getSystemInfo({
+			console.log('App Show');
+			this.checkShowWatermark();
+			uni.getSystemInfo({
 				success: (result) => {
 					// 获取手机系统的状态栏高度(不同手机的状态栏高度不同)
 					// console.log('当前手机的状态栏高度',result.statusBarHeight)
@@ -76,8 +75,34 @@
 		},
 		 
 		methods: {
-			// TODO:
-			resetLoginData() {
+		checkShowWatermark() {
+			const pages = getCurrentPages();
+			if (!pages.length) return;
+
+			const currentPage = pages[pages.length - 1];
+			const pagePath = currentPage.route;
+
+			const exclude = [
+				'pages/auth/login',
+				'pages/auth/register',
+				'pages/auth/registerUser'
+			];
+
+			this.showWatermark = !exclude.includes(pagePath);
+
+			const userInfo = uni.getStorageSync('userInfo') || {};
+			console.log('userInfo:', userInfo);
+			console.log('showWatermark:', this.showWatermark);
+			console.log('userName:', this.userName);
+			if (userInfo.userName) {
+				this.userName = userInfo.userName;
+			} else if (userInfo.nickName) {
+				this.userName = userInfo.nickName;
+			}
+			console.log('final userName:', this.userName);
+		},
+		// TODO:
+		resetLoginData() {
 				// this.globalData.expiresIn = '';
 				// this.globalData.sessionID = '';
 				// this.globalData.userInfo = {
@@ -153,5 +178,7 @@
 		    color: transparent;
 	    }
 	/* #endif */
+	
+	
 </style>
- 
+ 

+ 94 - 0
components/Watermark.vue

@@ -0,0 +1,94 @@
+<template>
+  <view class="watermark"  >
+    <view class="watermark-box">
+      <text class="text" v-for="(item, index) in count" :key="index" >{{localUserInfo.nickName || localUserInfo.userName || '' }}</text>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  name: 'Watermark',
+  props: {
+    userInfo: {
+      type: Object,
+      default: null
+    }
+  },
+  data() {
+    return {
+      count:40,
+      localUserInfo: this.userInfo || this.getUserInfo()
+    };
+  },
+  watch: {
+    // 监听props中的userInfo变化,当变化时更新本地userInfo
+    userInfo: {
+      handler(newVal) {
+        this.localUserInfo = newVal || this.getUserInfo();
+      },
+      deep: true
+    }
+  },
+  onShow() {
+    // 如果没有通过props传递userInfo,则从本地存储获取
+    if (!this.userInfo) {
+      this.localUserInfo = this.getUserInfo();
+    }
+  },
+  onLoad() {
+    // 如果没有通过props传递userInfo,则从本地存储获取
+    if (!this.userInfo) {
+      this.localUserInfo = this.getUserInfo();
+    }
+  },
+  methods: {
+    getUserInfo() {
+      try {
+        const userInfo = uni.getStorageSync('userInfo');
+        if (userInfo) {
+          // 尝试解析JSON字符串
+          return userInfo|| {};
+        }
+        return {};
+      } catch (error) {
+        console.error('获取用户信息失败:', error);
+        return {};
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.watermark {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100vw;
+  height: 100vh;
+  pointer-events: none;
+  z-index: 999999;
+  overflow: hidden;
+  font-size: 40rpx;
+}
+
+.watermark-box {
+  width: 200%;
+  height: 150%;
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-between;
+  align-items: flex-start;
+  transform: rotate(-20deg) translate(-25%, -25%);
+  color: rgba(196, 196, 196, 0.5);
+  padding: 0;
+}
+
+.text {
+  margin: 20rpx 15rpx;
+  font-weight: bold;
+  flex: 0 0 calc(20% - 30rpx);
+  text-align: center;
+}
+</style>

+ 4 - 2
main.js

@@ -8,11 +8,13 @@ Vue.use(uView)
 // uni.$u.config.unit = 'rpx'
   
 import utils from './utils/common.js'
-Vue.prototype.utils = utils;
- 
+Vue.prototype.utils = utils; 
+
 import {setData} from './utils/common.js'
 Vue.prototype.setData = setData;
 
+
+
 App.mpType = 'app'
 const app = new Vue({
     ...App

+ 36 - 1
package-lock.json

@@ -1,8 +1,43 @@
 {
     "name": "shop",
     "version": "1.0.0",
-    "lockfileVersion": 1,
+    "lockfileVersion": 2,
     "requires": true,
+    "packages": {
+        "": {
+            "name": "shop",
+            "version": "1.0.0",
+            "dependencies": {
+                "animate.css": "^3.7.2",
+                "dayjs": "^1.11.13",
+                "uqrcodejs": "^4.0.7",
+                "uview-ui": "^2.0.36"
+            }
+        },
+        "node_modules/animate.css": {
+            "version": "3.7.2",
+            "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-3.7.2.tgz",
+            "integrity": "sha512-0bE8zYo7C0KvgOYrSVfrzkbYk6IOTVPNqkiHg2cbyF4Pq/PXzilz4BRWA3hwEUBoMp5VBgrC29lQIZyhRWdBTw=="
+        },
+        "node_modules/dayjs": {
+            "version": "1.11.13",
+            "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
+            "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
+        },
+        "node_modules/uqrcodejs": {
+            "version": "4.0.7",
+            "resolved": "https://registry.npmjs.org/uqrcodejs/-/uqrcodejs-4.0.7.tgz",
+            "integrity": "sha512-84+aZmD2godCVI+93lxE3YUAPNY8zAJvNA7xRS7R7U+q57KzMDepBSfNCwoRUhWOfR6eHFoAOcHRPwsP6ka1cA=="
+        },
+        "node_modules/uview-ui": {
+            "version": "2.0.36",
+            "resolved": "https://registry.npmjs.org/uview-ui/-/uview-ui-2.0.36.tgz",
+            "integrity": "sha512-ASSZT6M8w3GTO1eFPbsgEFV0U5UujK+8pTNr+MSUbRNcRMC1u63DDTLJVeArV91kWM0bfAexK3SK9pnTqF9TtA==",
+            "engines": {
+                "HBuilderX": "^3.1.0"
+            }
+        }
+    },
     "dependencies": {
         "animate.css": {
             "version": "3.7.2",

+ 2 - 1
pages.json

@@ -1,6 +1,7 @@
 {
 	"easycom": {
-		"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
+		"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue",
+		"^Watermark$": "@/components/Watermark.vue"
 	},
 	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
 		{

+ 2 - 1
pages/auth/changePassword.vue

@@ -1,6 +1,7 @@
 <template>
 	<view class="setting-page">
-		<view class="content">
+		<Watermark  />
+			<view class="content">
 			<view class="info-item">
 				<text class="title">原密码</text>
 				<input class="input-field code-input" type="text" :password="!showOldPassword" v-model="oldPassword"

+ 1 - 0
pages/auth/forgetPassword.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="setting-page">
+		<Watermark  />
 		<view class="content">
 			<view class="info-item">
 				<text class="title">手机号码</text>

+ 1 - 0
pages/auth/register.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="setting-page">
+		<Watermark  />
 		<view class="content">
 			<view class="info-block">
 				<view class="info-title">组织归属</view>

+ 1 - 0
pages/auth/setting.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="setting-page">
+		<Watermark  />
 		<view class="content">
 			<view class="info-item" @click="toChangePassword">
 				<view class="label">修改密码</view>

+ 7 - 31
pages/home/index.vue

@@ -1,14 +1,12 @@
 <template>
 	<view class="container">
+		<!-- 水印组件 -->
+		<Watermark :userInfo="userInfo" />
 		<image class="bg" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/bg_bench.png" mode="widthFix"></image>
 		<view class="status_bar" :style="{height: statusBarHeight}"></view>
 		<view class="content">
 			<view class="title">工作台</view>
 			<view class="summary-section ">
-				<!-- <view class="summary-header">
-					<view class="summary-indicator"></view>
-					<text class="summary-title">互联网</text>
-				</view> -->
 				<view class="list">
 					<view class="item" @click="navTo('/pages_task/xlTask')">
 						<image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/xl.png"></image>
@@ -23,19 +21,8 @@
 						<text>审批中心</text>
 					</view>
 				</view>
-				<!-- <view class="summary-header">
-					<view class="summary-indicator"></view>
-					<text class="summary-title">行政管理</text>
-				</view> -->
-				<!-- <view class="list">
-					<view class="item" @click="navTo('/pages_task/approvalCenter')">
-						<image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/approval.png"></image>
-						<text>审批中心</text>
-					</view>
-				</view> -->
 			</view>
 		</view>
-
 	</view>
 </template>
 
@@ -43,19 +30,16 @@
 	export default {
 		data() {
 			return {
+				userInfo: {},
 				// 状态栏的高度
-				// statusBarHeight: uni.getStorageSync('menuInfo').statusBarHeight,
-				statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
+				statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px'
 			}
-		},
-		computed: {
-
-		},
-		watch: {
-
 		},
 		onLoad() {
 
+		},
+		onShow() {
+			this.userInfo = uni.getStorageSync('userInfo') || {};
 		},
 		onReachBottom() {},
 		// 分享给朋友
@@ -111,19 +95,15 @@
 				height: 88rpx;
 				text-align: center;
 				line-height: 88rpx;
-
 			}
-
 			.summary-section {
 				padding: 32rpx 24rpx;
 				display: flex;
 				flex-direction: column;
-
 				.summary-header {
 					display: flex;
 					align-items: center;
 					margin-bottom: 24rpx;
-
 					.summary-indicator {
 						width: 6rpx;
 						height: 32rpx;
@@ -131,7 +111,6 @@
 						border-radius: 40rpx;
 						margin-right: 16rpx;
 					}
-
 					.summary-title {
 						font-size: 36rpx;
 						font-weight: bold;
@@ -139,12 +118,10 @@
 					}
 				}
 			}
-
 			.list {
 				display: flex;
 				align-items: center;
 				margin-bottom: 40rpx;
-
 				.item {
 					display: flex;
 					flex-direction: column;
@@ -155,7 +132,6 @@
 					border-radius: 20rpx 20rpx 20rpx 20rpx;
 					font-size: 28rpx;
 					color: #333333;
-
 					.icon {
 						width: 88rpx;
 						height: 88rpx;

+ 31 - 26
pages/user/index.vue

@@ -1,5 +1,6 @@
 <template>
 	<view>
+		<Watermark :userInfo="userInfo" />
 		<view class="top-cont">
 			<image class="bg" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/bg_mine.png" mode="widthFix"></image>
 			<view class="top-inner">
@@ -45,7 +46,7 @@
 <script>
 	
 	import {
-		getCompanyUserInfo
+		getCompanyuserInfo
 	} from '@/api/user'
 	export default {
 		data() {
@@ -69,7 +70,6 @@
 						url: '/pages/auth/setting'
 					},
 				],
-				userInfo: {},
 				user: {
 					isPromoter: 0,
 					isWeixinAuth: 0,
@@ -97,9 +97,14 @@
 			this.userInfo = uni.getStorageSync('userInfo')
 			// 从本地缓存加载用户信息
 			if(this.userInfo){
-				this.getCompanyUserInfo()
+				this.getCompanyuserInfo()
 			}
 		},
+		// computed: {
+		// 	userInfo() {
+		// 		return uni.getStorageSync('userInfo') || {}
+		// 	}
+		// },
 		onReachBottom() {
 			console.log("onReachBottom")
 			if (this.$refs.product) {
@@ -165,30 +170,30 @@
 					url: '../home/web'
 				})
 			},
-			getCompanyUserInfo() {
-			if(!this.userInfo.userId){
-				return
-			}
-			getCompanyUserInfo(this.userInfo.userId).then(
-				res => {
-					if (res.code == 200) {
-						if (res.user != null) {
-							this.userInfo = res.user;
-						} else {
-							if (this.utils && this.utils.loginOut) {
-								this.utils.loginOut();
+			getCompanyuserInfo() {
+				if(!this.userInfo.userId){
+					return
+				}
+				getCompanyuserInfo(this.userInfo.userId).then(
+					res => {
+						if (res.code == 200) {
+							if (res.data) {
+								this.userInfo = res.data;
+							} else {
+								if (this.utils && this.utils.loginOut) {
+									this.utils.loginOut();
+								}
 							}
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: "请求失败",
+							});
 						}
-					} else {
-						uni.showToast({
-							icon: 'none',
-							title: "请求失败",
-						});
-					}
-				},
-				rej => {}
-			);
-		},
+					},
+					rej => {}
+				);
+			},
 			// 跳转页面
 			navgetTo(url) {
 				if (this.utils && this.utils.isLogin) {
@@ -210,7 +215,7 @@
 		},
 		computed: {
 			joinDays() {
-				if (!this.userInfo.createTime) return 0
+				if (!this.userInfo || !this.userInfo.userId || !this.userInfo.createTime) return 0
 				const createDate = new Date(this.userInfo.createTime.replace(/-/g, '/'))
 				const now = new Date()
 				const diffTime = now - createDate

+ 1 - 0
pages_speaker/gradeApplication.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="container">
+		<Watermark  />
 		<scroll-view class="content" scroll-y>
 			<!-- 驳回意见提示 -->
 			<view class="rejection-banner" v-if="rejectionInfo">

+ 1 - 0
pages_speaker/index.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="container">
+		<Watermark  />
 		<view class="top-box">
 			<view class="input-item">
 				<image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/search.png" mode=""></image>

+ 38 - 10
pages_speaker/lecturerDetail.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="container">
+		<Watermark  />
 		<view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
 		<view class="top">
 			<image class="return" @click="goBack" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/back_white.png"></image>
@@ -18,7 +19,7 @@
 							<text class="name">{{ lecturerInfo.doctorName||'未命名' }}</text>
 							<text class="identity" v-if="lecturerInfo.identity">{{ lecturerInfo.identity }}</text>
 						</view>
-						<text class="phone">{{ lecturerInfo.mobile ||'-'}}</text>
+						<text class="phone">{{ utils.parseIdCard(lecturerInfo.mobile) ||'-'}}</text>
 					</view>
 					<image class="avatar" :src="lecturerInfo.avatar"></image>
 				</view>
@@ -32,7 +33,7 @@
 				<view class="info-list">
 					<view class="info-item">
 						<text class="info-label">身份证号:</text>
-						<text class="info-value">{{ lecturerInfo.idCard ||'-'}}</text>
+						<text class="info-value">{{ utils.parseIdCard(lecturerInfo.idCard) ||'-'}}</text>
 					</view>
 					<view class="info-item">
 						<text class="info-label">公司:</text>
@@ -88,13 +89,15 @@
 					<view class="qualification-item">
 						<text class="qualification-label">医师执业证</text>
 						<view class="image-grid">
-							<image class="qualification-image"  :src=" lecturerInfo.licenseImage"></image>
+							<image v-for="(image, index) in licenseImages" :key="index" class="qualification-image" :src="image"></image>
+							<text v-if="licenseImages.length === 0" class="no-image">暂无图片</text>
 						</view>
 					</view>
 					<view class="qualification-item">
 						<text class="qualification-label">医师职称证/工牌</text>
 						<view class="image-grid">
-							<image class="qualification-image"  :src=" lecturerInfo.titleCertImage"></image>
+							<image v-for="(image, index) in titleCertImages" :key="index" class="qualification-image" :src="image"></image>
+							<text v-if="titleCertImages.length === 0" class="no-image">暂无图片</text>
 						</view>
 					</view>
 				</view>
@@ -113,7 +116,7 @@
 					</view>
 					<view class="info-item">
 						<text class="info-label">银行卡号:</text>
-						<text class="info-value">{{ lecturerInfo.bankCardNo||'-' }}</text>
+						<text class="info-value">{{ utils.parseIdCard(lecturerInfo.bankCardNo)||'-' }}</text>
 					</view>
 					<view class="info-item">
 						<text class="info-label">开户银行:</text>
@@ -222,6 +225,20 @@
 			maskedPassword() {
 				if (!this.lecturerInfo.password) return '';
 				return '*'.repeat(this.lecturerInfo.password.length);
+			},
+			licenseImages() {
+				if (!this.lecturerInfo.licenseImage) return [];
+				// 去除首尾空格和引号,然后按逗号分割
+				const images = this.lecturerInfo.licenseImage.trim().replace(/^"|"$/g, '').split(',');
+				// 过滤空字符串并去除每个URL的首尾空格
+				return images.filter(img => img.trim()).map(img => img.trim());
+			},
+			titleCertImages() {
+				if (!this.lecturerInfo.titleCertImage) return [];
+				// 去除首尾空格和引号,然后按逗号分割
+				const images = this.lecturerInfo.titleCertImage.trim().replace(/^"|"$/g, '').split(',');
+				// 过滤空字符串并去除每个URL的首尾空格
+				return images.filter(img => img.trim()).map(img => img.trim());
 			}
 		}
 	}
@@ -415,11 +432,22 @@
 					gap: 16rpx;
 
 					.qualification-image {
-						width: calc((100% - 32rpx) / 2);
-						height: 240rpx;
-						border-radius: 8rpx;
-						object-fit: cover;
-					}
+									width: calc((100% - 32rpx) / 2);
+									height: 240rpx;
+									border-radius: 8rpx;
+									object-fit: cover;
+								}
+								.no-image {
+									width: 100%;
+									height: 240rpx;
+									display: flex;
+									align-items: center;
+									justify-content: center;
+									font-size: 28rpx;
+									color: #999999;
+									background-color: #f5f5f5;
+									border-radius: 8rpx;
+								}
 				}
 			}
 		}

+ 1 - 0
pages_speaker/speakerInvitation.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="container">
+		<Watermark  />
 		<image class="bg" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/bg_invite.png" mode="aspectFill"></image>
 		<!-- 状态栏占位(微信小程序原生适配) -->
 		<view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>

+ 0 - 291
pages_task/activityDetail.vue

@@ -1,291 +0,0 @@
-<template>
-	<view class="container">
-		<!-- 状态栏占位 -->
-		<view class="status-bar" :style="{height: statusBarHeight}"></view>
-		
-		<!-- 顶部导航栏 -->
-		<view class="header">
-			<view class="back-btn" @click="goBack">
-				<image src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/back.png" mode="aspectFill"></image>
-			</view>
-			<view class="title">活动详情</view>
-			<view class="header-right">
-				<text class="more-icon">⋯</text>
-				<text class="more-icon">○</text>
-			</view>
-		</view>
-		
-		<scroll-view class="content" scroll-y>
-			<!-- 活动头部 -->
-			<view class="activity-header">
-				<view class="logo-section">
-					<view class="logo-icon">预定</view>
-					<view class="logo-text">YOUR LOGO</view>
-					<view class="logo-url">www.gaoding.com</view>
-				</view>
-				
-				<view class="activity-title">
-					<view class="title-main">{{ activityData.title }}</view>
-					<view class="title-en">{{ activityData.titleEn }}</view>
-					<view class="title-date">{{ activityData.date }}</view>
-				</view>
-			</view>
-			
-			<!-- 活动主图 -->
-			<view class="activity-banner">
-				<image class="banner-image" :src="activityData.bannerImage" mode="aspectFill"></image>
-				<view class="banner-text">{{ activityData.bannerText }}</view>
-			</view>
-		</scroll-view>
-		
-		<!-- 底部按钮 -->
-		<view class="bottom-btn" :class="activityData.buttonClass" @click="handleAction">
-			{{ activityData.buttonText }}
-		</view>
-	</view>
-</template>
-
-<script>
-import { getActivityDetail } from '@/api-js/medicationSurvey'
-export default {
-	data() {
-		return {
-			statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
-			activityId: '',
-			activityData: {
-				title: '世界关节炎日',
-				titleEn: 'WORLD ARTHRISTIS DAY',
-				date: '2024年10月12日',
-				bannerImage: '',
-				bannerText: '早预防・早诊断・早治疗',
-				status: 'notStarted', // notStarted, inProgress, ended
-				buttonText: '活动未开始',
-				buttonClass: 'not-started',
-				completedCount: 0,
-				totalCount: 3
-			}
-		}
-	},
-	onLoad(options) {
-		if (options.id) {
-			this.activityId = options.id
-			this.loadData()
-		}
-	},
-	methods: {
-		goBack() {
-			uni.navigateBack()
-		},
-		handleAction() {
-			if (this.activityData.status === 'notStarted') {
-				uni.showToast({
-					icon: 'none',
-					title: '活动未开始'
-				})
-			} else if (this.activityData.status === 'ended') {
-				uni.showToast({
-					icon: 'none',
-					title: '活动已结束'
-				})
-			} else {
-				// 跳转到病例征集页面
-				uni.navigateTo({
-					url: `/pages_task/caseCollection?activityId=${this.activityId}`
-				})
-			}
-		},
-		async loadData() {
-			try {
-				uni.showLoading({ title: '加载中...' })
-				const res = await getActivityDetail({ id: this.activityId })
-				uni.hideLoading()
-				if (res.code === 200 && res.data) {
-					this.activityData = { ...this.activityData, ...res.data }
-					this.updateButtonText()
-				}
-			} catch (e) {
-				uni.hideLoading()
-				console.error('加载数据失败', e)
-			}
-		},
-		updateButtonText() {
-			if (this.activityData.status === 'notStarted') {
-				this.activityData.buttonText = '活动未开始'
-				this.activityData.buttonClass = 'not-started'
-			} else if (this.activityData.status === 'ended') {
-				this.activityData.buttonText = '活动已结束'
-				this.activityData.buttonClass = 'ended'
-			} else {
-				this.activityData.buttonText = `上传病例 ${this.activityData.completedCount}/${this.activityData.totalCount}`
-				this.activityData.buttonClass = 'upload-case'
-			}
-		}
-	}
-}
-</script>
-
-<style lang="scss" scoped>
-.container {
-	min-height: 100vh;
-	background: linear-gradient(180deg, #E6F3FF 0%, #FFFFFF 100%);
-	display: flex;
-	flex-direction: column;
-}
-
-.status-bar {
-	width: 100%;
-	background: transparent;
-}
-
-.header {
-	position: relative;
-	height: 88rpx;
-	display: flex;
-	align-items: center;
-	justify-content: center;
-	background: transparent;
-	
-	.back-btn {
-		position: absolute;
-		left: 24rpx;
-		width: 40rpx;
-		height: 40rpx;
-		
-		image {
-			width: 100%;
-			height: 100%;
-		}
-	}
-	
-	.title {
-		font-size: 36rpx;
-		font-weight: bold;
-		color: #333;
-	}
-	
-	.header-right {
-		position: absolute;
-		right: 24rpx;
-		display: flex;
-		align-items: center;
-		gap: 16rpx;
-		
-		.more-icon {
-			font-size: 32rpx;
-			color: #333;
-		}
-	}
-}
-
-.content {
-	flex: 1;
-	padding: 24rpx;
-}
-
-.activity-header {
-	margin-bottom: 32rpx;
-	
-	.logo-section {
-		display: flex;
-		align-items: center;
-		gap: 16rpx;
-		margin-bottom: 24rpx;
-		
-		.logo-icon {
-			width: 48rpx;
-			height: 48rpx;
-			background: #388BFF;
-			border-radius: 50%;
-			display: flex;
-			align-items: center;
-			justify-content: center;
-			font-size: 20rpx;
-			color: #fff;
-		}
-		
-		.logo-text {
-			font-size: 28rpx;
-			font-weight: bold;
-			color: #388BFF;
-		}
-		
-		.logo-url {
-			font-size: 24rpx;
-			color: #388BFF;
-		}
-	}
-	
-	.activity-title {
-		.title-main {
-			font-size: 48rpx;
-			font-weight: bold;
-			color: #388BFF;
-			margin-bottom: 8rpx;
-		}
-		
-		.title-en {
-			font-size: 36rpx;
-			font-weight: bold;
-			color: #388BFF;
-			margin-bottom: 8rpx;
-		}
-		
-		.title-date {
-			font-size: 28rpx;
-			color: #388BFF;
-		}
-	}
-}
-
-.activity-banner {
-	position: relative;
-	width: 100%;
-	height: 600rpx;
-	border-radius: 16rpx;
-	overflow: hidden;
-	background: linear-gradient(135deg, #E6F3FF 0%, #FFFFFF 100%);
-	
-	.banner-image {
-		width: 100%;
-		height: 100%;
-	}
-	
-	.banner-text {
-		position: absolute;
-		bottom: 40rpx;
-		left: 50%;
-		transform: translateX(-50%);
-		font-size: 28rpx;
-		color: #fff;
-		white-space: nowrap;
-	}
-}
-
-.bottom-btn {
-	position: fixed;
-	bottom: 0;
-	left: 0;
-	right: 0;
-	height: 88rpx;
-	display: flex;
-	align-items: center;
-	justify-content: center;
-	font-size: 32rpx;
-	color: #fff;
-	font-weight: 500;
-	z-index: 100;
-	
-	&.not-started {
-		background: #87CEEB;
-	}
-	
-	&.upload-case {
-		background: #388BFF;
-	}
-	
-	&.ended {
-		background: #999;
-	}
-}
-</style>
-

+ 2 - 1
pages_task/approvalCenter.vue

@@ -1,7 +1,8 @@
 <template>
 	<view class="container">
+		<Watermark  />
 		<!-- 搜索+筛选栏 -->
-		<view class="top-box">
+			<view class="top-box">
 			<view class="input-item">
 				<image class="icon search-icon"
 					src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/search.png" mode="widthFix"></image>

+ 28 - 6
pages_task/approvalTaskDetail.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="container">
+		<Watermark  />
 		<view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
 		<view class="top">
 			<image class="return" @click="goBack"
@@ -53,11 +54,11 @@
 					</view>
 					<view class="info-item">
 						<text class="info-label">手机号码</text>
-						<text class="info-value">{{ auditData.businessData.mobile||'-' }}</text>
+						<text class="info-value">{{ utils.parseIdCard(auditData.businessData.mobile)||'-' }}</text>
 					</view>
 					<view class="info-item">
 						<text class="info-label">身份证号</text>
-						<text class="info-value">{{ auditData.businessData.idCard||'-'}}</text>
+						<text class="info-value">{{ utils.parseIdCard(auditData.businessData.idCard)||'-'}}</text>
 					</view>
 					<view class="info-item">
 						<text class="info-label">机构名称</text>
@@ -90,9 +91,9 @@
 						<text class="info-value">{{ auditData.businessData.department||'-'}}</text>
 					</view>
 					<view class="info-item">
-						<text class="info-label">职称</text>
-						<text class="info-value">{{ auditData.businessData.jobTitle||'-'}}</text>
-					</view>
+					<text class="info-label">职称</text>
+					<text class="info-value">{{ getHospitalTitle(auditData.businessData.jobTitle)||'-'}}</text>
+				</view>
 					<view class="info-item">
 						<text class="info-label">第三方业务编码</text>
 						<text class="info-value">{{ auditData.businessData.thirdPartyCode||'-'}}</text>
@@ -642,6 +643,8 @@
 </template>
 
 <script>
+import utils from '@/utils/common.js'
+
 	import {
 		doAudit,
 		doCreateAudit,
@@ -680,7 +683,8 @@
 					show: false,
 					urls: [],
 					current: 0
-				}
+				},
+				hospitalTitle: [],
 			}
 		},
 		computed: {
@@ -690,7 +694,13 @@
 			if (options.taskId) {
 				this.taskId = options.taskId
 				this.loadData()
+					utils.getDicts("hospital_title").then(res => {
+
+			this.hospitalTitle = res || [];
+			console.log(this.hospitalTitle, 'hospitalTitle')
+		});
 			}
+		
 		},
 		methods: {
 			getStatusBarHeight() {
@@ -1015,6 +1025,18 @@
 					console.error('判断用户是否在最新审核人中失败:', error);
 					return false;
 				}
+			},
+			// 根据职称值获取职称名称
+			getHospitalTitle(jobTitle) {
+				console.log(jobTitle, 'jobTitle')
+				console.log(this.hospitalTitle, 'hospitalTitle')
+
+				if (!jobTitle || !this.hospitalTitle ) {
+					return '-';
+				}
+				const title = this.hospitalTitle.find(item => item.dictValue == jobTitle);
+				console.log(title, 'title')
+				return title ? title.dictLabel : '-';	
 			}
 		}
 	}

+ 0 - 511
pages_task/caseCollection.vue

@@ -1,511 +0,0 @@
-<template>
-	<view class="container">
-		<!-- 状态栏占位 -->
-		<view class="status-bar" :style="{height: statusBarHeight}"></view>
-		
-		<!-- 顶部导航栏 -->
-		<view class="header">
-			<view class="back-btn" @click="goBack">
-				<image src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/back.png" mode="aspectFill"></image>
-			</view>
-			<view class="title">病例征集</view>
-			<view class="header-right">
-				<text class="more-icon">⋯</text>
-				<text class="more-icon">○</text>
-			</view>
-		</view>
-		
-		<scroll-view class="content" scroll-y>
-			<!-- 表单标题 -->
-			<view class="form-header">
-				<view class="form-title">{{ formData.title }}</view>
-				<view class="form-tips">
-					<view class="tip-item">请您根据患者真实情况选择并填写</view>
-					<view class="tip-item">我们承诺对您及患者所提供的所有信息严格保密</view>
-				</view>
-			</view>
-			
-			<!-- 表单内容 -->
-			<view class="form-section">
-				<!-- 患者姓名 -->
-				<view class="form-item">
-					<view class="form-label">
-						<text class="required">*</text>
-						<text>1、患者姓名</text>
-					</view>
-					<input 
-						class="form-input" 
-						v-model="formData.patientName" 
-						placeholder="请输入患者姓名"
-					/>
-				</view>
-				
-				<!-- 患者性别 -->
-				<view class="form-item">
-					<view class="form-label">
-						<text class="required">*</text>
-						<text>2、患者性别</text>
-					</view>
-					<view class="radio-group">
-						<view 
-							class="radio-item" 
-							:class="{ active: formData.patientGender === 'male' }"
-							@click="formData.patientGender = 'male'">
-							<view class="radio-icon">
-								<text v-if="formData.patientGender === 'male'">✓</text>
-							</view>
-							<text>男</text>
-						</view>
-						<view 
-							class="radio-item" 
-							:class="{ active: formData.patientGender === 'female' }"
-							@click="formData.patientGender = 'female'">
-							<view class="radio-icon">
-								<text v-if="formData.patientGender === 'female'">✓</text>
-							</view>
-							<text>女</text>
-						</view>
-					</view>
-				</view>
-				
-				<!-- 患者年龄 -->
-				<view class="form-item">
-					<view class="form-label">
-						<text class="required">*</text>
-						<text>3、患者年龄</text>
-					</view>
-					<input 
-						class="form-input" 
-						v-model="formData.patientAge" 
-						type="number"
-						placeholder="请输入患者年龄 (岁)"
-					/>
-				</view>
-				
-				<!-- 处方日期 -->
-				<view class="form-item">
-					<view class="form-label">
-						<text class="required">*</text>
-						<text>4、处方日期</text>
-					</view>
-					<picker mode="date" :value="formData.prescriptionDate" @change="onDateChange">
-						<view class="form-input picker-input" :class="{ placeholder: !formData.prescriptionDate }">
-							{{ formData.prescriptionDate || '请选择处方日期' }}
-							<text class="calendar-icon">📅</text>
-						</view>
-					</picker>
-				</view>
-				
-				<!-- 心脏病类型 -->
-				<view class="form-item">
-					<view class="form-label">
-						<text class="required">*</text>
-						<text>5、您被诊断的心脏病类型 (多选)</text>
-					</view>
-					<view class="checkbox-group">
-						<view 
-							class="checkbox-item" 
-							:class="{ active: formData.diseaseTypes.includes('coronary') }"
-							@click="toggleDiseaseType('coronary')">
-							<view class="checkbox-icon">
-								<text v-if="formData.diseaseTypes.includes('coronary')">✓</text>
-							</view>
-							<text>冠心病</text>
-						</view>
-						<view 
-							class="checkbox-item" 
-							:class="{ active: formData.diseaseTypes.includes('heartFailure') }"
-							@click="toggleDiseaseType('heartFailure')">
-							<view class="checkbox-icon">
-								<text v-if="formData.diseaseTypes.includes('heartFailure')">✓</text>
-							</view>
-							<text>心力衰竭</text>
-						</view>
-						<view 
-							class="checkbox-item" 
-							:class="{ active: formData.diseaseTypes.includes('arrhythmia') }"
-							@click="toggleDiseaseType('arrhythmia')">
-							<view class="checkbox-icon">
-								<text v-if="formData.diseaseTypes.includes('arrhythmia')">✓</text>
-							</view>
-							<text>心律失常</text>
-						</view>
-					</view>
-				</view>
-				
-				<!-- 图片上传 -->
-				<view class="form-item">
-					<view class="form-label">
-						<text class="required">*</text>
-						<text>6、图片上传</text>
-					</view>
-					<view class="upload-section">
-						<view class="upload-item" v-for="(image, index) in formData.images" :key="index">
-							<image class="uploaded-image" :src="image" mode="aspectFill"></image>
-							<view class="delete-btn" @click="removeImage(index)">×</view>
-						</view>
-						<view class="upload-item upload-placeholder" @click="chooseImage" v-if="formData.images.length < 2">
-							<text class="camera-icon">📷</text>
-						</view>
-					</view>
-				</view>
-			</view>
-		</scroll-view>
-		
-		<!-- 提交按钮 -->
-		<view class="submit-btn" @click="handleSubmit">提交</view>
-	</view>
-</template>
-
-<script>
-import { submitCaseCollection } from '@/api-js/medicationSurvey'
-export default {
-	data() {
-		return {
-			statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
-			activityId: '',
-			formData: {
-				title: '心脏相关疾病病例征集表',
-				patientName: '',
-				patientGender: 'male',
-				patientAge: '',
-				prescriptionDate: '',
-				diseaseTypes: ['coronary', 'heartFailure'],
-				images: []
-			}
-		}
-	},
-	onLoad(options) {
-		if (options.activityId) {
-			this.activityId = options.activityId
-		}
-	},
-	methods: {
-		goBack() {
-			uni.navigateBack()
-		},
-		onDateChange(e) {
-			this.formData.prescriptionDate = e.detail.value
-		},
-		toggleDiseaseType(type) {
-			const index = this.formData.diseaseTypes.indexOf(type)
-			if (index > -1) {
-				this.formData.diseaseTypes.splice(index, 1)
-			} else {
-				this.formData.diseaseTypes.push(type)
-			}
-		},
-		chooseImage() {
-			uni.chooseImage({
-				count: 2 - this.formData.images.length,
-				sizeType: ['compressed'],
-				sourceType: ['album', 'camera'],
-				success: (res) => {
-					this.formData.images = [...this.formData.images, ...res.tempFilePaths]
-				}
-			})
-		},
-		removeImage(index) {
-			this.formData.images.splice(index, 1)
-		},
-		async handleSubmit() {
-			// 表单验证
-			if (!this.formData.patientName) {
-				uni.showToast({
-					icon: 'none',
-					title: '请输入患者姓名'
-				})
-				return
-			}
-			if (!this.formData.patientAge) {
-				uni.showToast({
-					icon: 'none',
-					title: '请输入患者年龄'
-				})
-				return
-			}
-			if (!this.formData.prescriptionDate) {
-				uni.showToast({
-					icon: 'none',
-					title: '请选择处方日期'
-				})
-				return
-			}
-			if (this.formData.diseaseTypes.length === 0) {
-				uni.showToast({
-					icon: 'none',
-					title: '请至少选择一种心脏病类型'
-				})
-				return
-			}
-			if (this.formData.images.length === 0) {
-				uni.showToast({
-					icon: 'none',
-					title: '请至少上传一张图片'
-				})
-				return
-			}
-			
-			try {
-				uni.showLoading({ title: '提交中...' })
-				const res = await submitCaseCollection({
-					activityId: this.activityId,
-					...this.formData
-				})
-				uni.hideLoading()
-				if (res.code === 200) {
-					uni.showToast({
-						icon: 'success',
-						title: '提交成功'
-					})
-					setTimeout(() => {
-						uni.navigateBack()
-					}, 1500)
-				} else {
-					uni.showToast({
-						icon: 'none',
-						title: res.msg || '提交失败'
-					})
-				}
-			} catch (e) {
-				uni.hideLoading()
-				uni.showToast({
-					icon: 'none',
-					title: '提交失败'
-				})
-			}
-		}
-	}
-}
-</script>
-
-<style lang="scss" scoped>
-.container {
-	min-height: 100vh;
-	background: linear-gradient(180deg, #E6F3FF 0%, #FFFFFF 100%);
-	display: flex;
-	flex-direction: column;
-}
-
-.status-bar {
-	width: 100%;
-	background: transparent;
-}
-
-.header {
-	position: relative;
-	height: 88rpx;
-	display: flex;
-	align-items: center;
-	justify-content: center;
-	background: transparent;
-	
-	.back-btn {
-		position: absolute;
-		left: 24rpx;
-		width: 40rpx;
-		height: 40rpx;
-		
-		image {
-			width: 100%;
-			height: 100%;
-		}
-	}
-	
-	.title {
-		font-size: 36rpx;
-		font-weight: bold;
-		color: #333;
-	}
-	
-	.header-right {
-		position: absolute;
-		right: 24rpx;
-		display: flex;
-		align-items: center;
-		gap: 16rpx;
-		
-		.more-icon {
-			font-size: 32rpx;
-			color: #333;
-		}
-	}
-}
-
-.content {
-	flex: 1;
-	padding: 24rpx;
-}
-
-.form-header {
-	margin-bottom: 32rpx;
-	
-	.form-title {
-		font-size: 36rpx;
-		font-weight: bold;
-		color: #333;
-		margin-bottom: 16rpx;
-	}
-	
-	.form-tips {
-		.tip-item {
-			font-size: 24rpx;
-			color: #666;
-			margin-bottom: 8rpx;
-		}
-	}
-}
-
-.form-section {
-	background: #fff;
-	border-radius: 16rpx;
-	padding: 24rpx;
-}
-
-.form-item {
-	margin-bottom: 32rpx;
-	
-	&:last-child {
-		margin-bottom: 0;
-	}
-	
-	.form-label {
-		display: flex;
-		align-items: center;
-		font-size: 28rpx;
-		color: #333;
-		margin-bottom: 16rpx;
-		
-		.required {
-			color: #FF5030;
-			margin-right: 4rpx;
-		}
-	}
-	
-	.form-input {
-		width: 100%;
-		height: 80rpx;
-		padding: 0 24rpx;
-		background: #f5f5f5;
-		border-radius: 8rpx;
-		font-size: 28rpx;
-		color: #333;
-		
-		&.placeholder {
-			color: #999;
-		}
-		
-		&.picker-input {
-			display: flex;
-			align-items: center;
-			justify-content: space-between;
-			
-			.calendar-icon {
-				font-size: 32rpx;
-			}
-		}
-	}
-	
-	.radio-group,
-	.checkbox-group {
-		display: flex;
-		gap: 24rpx;
-		
-		.radio-item,
-		.checkbox-item {
-			display: flex;
-			align-items: center;
-			gap: 8rpx;
-			font-size: 28rpx;
-			color: #333;
-			
-			.radio-icon,
-			.checkbox-icon {
-				width: 40rpx;
-				height: 40rpx;
-				border: 2rpx solid #ddd;
-				border-radius: 50%;
-				display: flex;
-				align-items: center;
-				justify-content: center;
-				font-size: 24rpx;
-				color: #388BFF;
-			}
-			
-			.checkbox-icon {
-				border-radius: 4rpx;
-			}
-			
-			&.active {
-				.radio-icon,
-				.checkbox-icon {
-					border-color: #388BFF;
-					background: #E6F7FF;
-				}
-			}
-		}
-	}
-	
-	.upload-section {
-		display: flex;
-		gap: 16rpx;
-		flex-wrap: wrap;
-		
-		.upload-item {
-			width: 200rpx;
-			height: 200rpx;
-			border-radius: 8rpx;
-			overflow: hidden;
-			position: relative;
-			
-			.uploaded-image {
-				width: 100%;
-				height: 100%;
-			}
-			
-			.delete-btn {
-				position: absolute;
-				top: 8rpx;
-				right: 8rpx;
-				width: 40rpx;
-				height: 40rpx;
-				background: rgba(0, 0, 0, 0.5);
-				border-radius: 50%;
-				display: flex;
-				align-items: center;
-				justify-content: center;
-				font-size: 32rpx;
-				color: #fff;
-			}
-			
-			&.upload-placeholder {
-				background: #f5f5f5;
-				display: flex;
-				align-items: center;
-				justify-content: center;
-				
-				.camera-icon {
-					font-size: 60rpx;
-				}
-			}
-		}
-	}
-}
-
-.submit-btn {
-	position: fixed;
-	bottom: 0;
-	left: 0;
-	right: 0;
-	height: 88rpx;
-	background: #388BFF;
-	display: flex;
-	align-items: center;
-	justify-content: center;
-	font-size: 32rpx;
-	color: #fff;
-	font-weight: 500;
-	z-index: 100;
-}
-</style>
-

+ 253 - 546
pages_task/completeTask.vue

@@ -1,388 +1,162 @@
 <template>
 	<view class="container">
-
+		<Watermark  />
+		<Step :step="currentStep" :stepsData="currentText" />
 
 		<scroll-view class="content" scroll-y>
-			<!-- 标题 -->
-			<view class="form-section">
-				<view class="form-label">
-					<text class="required">*</text>
-					<text>标题</text>
-				</view>
-				<view class="form-input-wrapper">
-					<textarea class="form-input" v-model="formData.title" placeholder="请输入标题" maxlength="50"
-						@input="onTitleInput"></textarea>
-					<view class="char-count">{{ titleLength }}/50</view>
-				</view>
-			</view>
-
-			<!-- 摘要 -->
-			<view class="form-section">
-				<view class="form-label">
-					<text>摘要 (选填)</text>
-				</view>
-				<view class="form-input-wrapper">
-					<textarea class="form-input" v-model="formData.summary" placeholder="请输入摘要" maxlength="100"
-						@input="onSummaryInput"></textarea>
-					<view class="char-count">{{ summaryLength }}/100</view>
+			<!-- 任务信息 -->
+			<view class="task-info-section">
+				<view class="section-title">任务信息</view>
+				<view class="info-item">
+					<view class="info-label">任务名称:</view>
+					<view class="info-value">{{ taskInfo.taskName || '-' }}</view>
 				</view>
-			</view>
-
-			<!-- 项目分组 -->
-			<view class="form-section">
-				<view class="form-label">
-					<text class="required">*</text>
-					<text>项目分组</text>
+				<view class="info-item">
+					<view class="info-label">任务类型:</view>
+					<view class="info-value">{{ taskInfo.taskType || '-' }}</view>
 				</view>
-				<view class="form-select" @click="showGroupPicker = true">
-					<text :class="formData.groupId ? '' : 'placeholder'">
-						{{ formData.groupName || '请选择分组' }}
-					</text>
-					<text class="arrow-right">></text>
+				<view class="info-item">
+					<view class="info-label">任务描述:</view>
+					<view class="info-value">{{ taskInfo.taskDesc || '-' }}</view>
 				</view>
 			</view>
 
-			<!-- 项目标签 -->
-			<view class="form-section">
-				<view class="form-label">
-					<text class="required">*</text>
-					<text>项目标签</text>
+			<!-- 完成情况 -->
+			<view class="complete-section">
+				<view class="section-title">完成情况</view>
+				<view class="complete-item">
+					<view class="complete-label">已完成客户:</view>
+					<view class="complete-value">{{ completedCustomers.length }} / {{ totalCustomers }}</view>
 				</view>
-				<view class="form-select" @click="showTagPicker = true">
-					<text :class="formData.tagId ? '' : 'placeholder'">
-						{{ formData.tagName || '请选择标签' }}
-					</text>
-					<text class="arrow-right">></text>
+				<view class="progress-bar">
+					<view class="progress-fill" :style="{ width: progressPercentage + '%' }"></view>
 				</view>
 			</view>
 
-			<!-- 上传封面 -->
-			<view class="form-section">
-				<view class="form-label">
-					<text class="required">*</text>
-					<text>上传封面</text>
-				</view>
-				<view class="form-tips">仅支持jpg/png文件,单个图片不超过2M</view>
-				<view class="upload-cover" @click="chooseCoverImage">
-					<image v-if="formData.coverImage" :src="formData.coverImage" mode="aspectFill"></image>
-					<view v-else class="upload-placeholder">
-						<text class="camera-icon">📷</text>
-					</view>
-				</view>
-			</view>
-
-			<!-- 上传附件 -->
-			<view class="form-section">
-				<view class="form-label">
-					<text class="required">*</text>
-					<text>上传附件</text>
-				</view>
-				<view class="form-tips">支持MP4等文件,单个文件不超过500M</view>
-				<view class="attachment-list">
-					<view class="attachment-item" v-for="(item, index) in formData.attachments" :key="index">
-						<text class="attachment-icon">📎</text>
-						<view class="attachment-info">
-							<text class="attachment-name">{{ item.name }}</text>
-							<text class="attachment-size">{{ item.size }}</text>
+			<!-- 客户列表 -->
+			<view class="customer-list">
+				<view class="customer-item" v-for="(customer, index) in customerList" :key="customer.id">
+					<view class="left">
+						<image class="head" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/my_heads_icon.png"></image>
+						<view class="customer-info">
+							<view class="customer-header">
+								<view class="customer-name">{{ customer.doctorName ||'-'}}</view>
+								<view class="customer-status" :class="customer.status === 'completed' ? 'completed' : 'pending'">
+									{{ customer.status === 'completed' ? '已完成' : '待完成' }}
+								</view>
+							</view>
+							<view class="customer-details">
+								<view class="customer-hospital">{{ customer.cityName||'-' }}</view>
+								<view class="customer-department">{{ customer.department ||'-'}}</view>
+							</view>
 						</view>
-						<text class="attachment-delete" @click="removeAttachment(index)">×</text>
 					</view>
-					<view class="add-attachment" @click="chooseAttachment">
-						<text class="add-icon">+</text>
-						<text>添加附件</text>
+					<view class="action-btn" v-if="customer.status === 'pending'" @click="completeCustomer(customer)">
+						完成
 					</view>
 				</view>
 			</view>
 		</scroll-view>
 
-		<!-- 提交按钮 -->
-		<view class="submit-btn" @click="handleSubmit">提交</view>
-
-		<!-- 分组选择弹窗 -->
-		<view class="picker-popup" v-if="showGroupPicker" @click="showGroupPicker = false">
-			<view class="picker-content" @click.stop>
-				<view class="picker-header">
-					<view class="picker-cancel" @click="showGroupPicker = false">取消</view>
-					<view class="picker-title">选择分组</view>
-					<view class="picker-confirm" @click="confirmGroup">确定</view>
-				</view>
-				<view class="picker-body">
-					<view class="picker-item" :class="{ active: tempGroupId === item.id }"
-						v-for="(item, index) in groupOptions" :key="index"
-						@click="tempGroupId = item.id; tempGroupName = item.name">
-						{{ item.name }}
-					</view>
-				</view>
-			</view>
-		</view>
-
-		<!-- 标签选择弹窗 -->
-		<view class="picker-popup" v-if="showTagPicker" @click="showTagPicker = false">
-			<view class="picker-content" @click.stop>
-				<view class="picker-header">
-					<view class="picker-cancel" @click="showTagPicker = false">取消</view>
-					<view class="picker-title">选择标签</view>
-					<view class="picker-confirm" @click="confirmTag">确定</view>
-				</view>
-				<view class="picker-body">
-					<view class="picker-item" :class="{ active: tempTagId === item.id }"
-						v-for="(item, index) in tagOptions" :key="index"
-						@click="tempTagId = item.id; tempTagName = item.name">
-						{{ item.name }}
-					</view>
-				</view>
+		<!-- 底部操作栏 -->
+		<view class="bottom-bar">
+			<view class="action-buttons">
+				<view class="btn btn-cancel" @click="handlePrev">上一步</view>
+				<view class="btn btn-submit" @click="handleNext" :disabled="completedCustomers.length === 0">提交</view>
 			</view>
 		</view>
 	</view>
 </template>
 
 <script>
-	// import { submitTask, getGroupOptions, getTagOptions, uploadFile } from '@/api-js/airClassroom'
+import Step from '@/pages_task/components/step.vue'
 	export default {
+		components: {
+			Step
+		},
 		data() {
 			return {
-				statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
-				taskId: '',
-				isEdit: false,
-				showGroupPicker: false,
-				showTagPicker: false,
-				tempGroupId: '',
-				tempGroupName: '',
-				tempTagId: '',
-				tempTagName: '',
-				formData: {
-					title: '',
-					summary: '',
-					groupId: '',
-					groupName: '',
-					tagId: '',
-					tagName: '',
-					coverImage: '',
-					attachments: []
-				},
-				groupOptions: [{
-						id: '1',
-						name: '学术'
+				currentText: [{
+						id: 1,
+						stepNumber: 1,
+						title: '任务详情'
 					},
 					{
-						id: '2',
-						name: '临床'
+						id: 2,
+						stepNumber: 2,
+						title: '完成任务'
 					},
 					{
-						id: '3',
-						name: '科研'
+						id: 3,
+						stepNumber: 3,
+						title: '提交成功'
 					}
 				],
-				tagOptions: [{
-						id: '1',
-						name: '长视频'
-					},
-					{
-						id: '2',
-						name: '短视频'
-					},
-					{
-						id: '3',
-						name: '文章'
-					}
-				]
+				currentStep: 2,
+				taskInfo: {},
+				customerList: [],
+				completedCustomers: []
 			}
 		},
+		onLoad() {
+			this.loadTaskData()
+			this.loadCustomerData()
+		},
 		computed: {
-			titleLength() {
-				return this.formData.title.length
+			totalCustomers() {
+				return this.customerList.length
 			},
-			summaryLength() {
-				return this.formData.summary.length
-			}
-		},
-		onLoad(options) {
-			if (options.id) {
-				this.taskId = options.id
-			}
-			if (options.edit === 'true') {
-				this.isEdit = true
-				this.loadTaskData()
+			progressPercentage() {
+				if (this.totalCustomers === 0) return 0
+				return Math.round((this.completedCustomers.length / this.totalCustomers) * 100)
 			}
-			this.loadOptions()
 		},
 		methods: {
-			goBack() {
-				uni.navigateBack()
-			},
-			onTitleInput(e) {
-				this.formData.title = e.detail.value
-			},
-			onSummaryInput(e) {
-				this.formData.summary = e.detail.value
-			},
-			confirmGroup() {
-				this.formData.groupId = this.tempGroupId
-				this.formData.groupName = this.tempGroupName
-				this.showGroupPicker = false
-			},
-			confirmTag() {
-				this.formData.tagId = this.tempTagId
-				this.formData.tagName = this.tempTagName
-				this.showTagPicker = false
-			},
-			chooseCoverImage() {
-				uni.chooseImage({
-					count: 1,
-					sizeType: ['compressed'],
-					sourceType: ['album', 'camera'],
-					success: async (res) => {
-						try {
-							uni.showLoading({
-								title: '上传中...'
-							})
-							const uploadRes = await uploadFile({
-								file: res.tempFilePaths[0],
-								type: 'cover'
-							})
-							uni.hideLoading()
-							if (uploadRes.code === 200 && uploadRes.data) {
-								this.formData.coverImage = uploadRes.data.url
-							}
-						} catch (e) {
-							uni.hideLoading()
-							uni.showToast({
-								icon: 'none',
-								title: '上传失败'
-							})
-						}
-					}
-				})
-			},
-			chooseAttachment() {
-				uni.chooseFile({
-					count: 1,
-					type: 'file',
-					success: async (res) => {
-						const file = res.tempFiles[0]
-						if (file.size > 500 * 1024 * 1024) {
-							uni.showToast({
-								icon: 'none',
-								title: '文件大小不能超过500M'
-							})
-							return
-						}
-						try {
-							uni.showLoading({
-								title: '上传中...'
-							})
-							const uploadRes = await uploadFile({
-								file: file.path,
-								type: 'attachment'
-							})
-							uni.hideLoading()
-							if (uploadRes.code === 200 && uploadRes.data) {
-								this.formData.attachments.push({
-									name: file.name,
-									size: this.formatFileSize(file.size),
-									url: uploadRes.data.url
-								})
-							}
-						} catch (e) {
-							uni.hideLoading()
-							uni.showToast({
-								icon: 'none',
-								title: '上传失败'
-							})
-						}
-					}
-				})
-			},
-			removeAttachment(index) {
-				this.formData.attachments.splice(index, 1)
+			loadTaskData() {
+				// 从本地存储获取任务信息
+				const taskInfo = uni.getStorageSync('taskInfo')
+				if (taskInfo) {
+					this.taskInfo = JSON.parse(taskInfo)
+				}
 			},
-			formatFileSize(bytes) {
-				if (bytes < 1024) return bytes + 'B'
-				if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + 'KB'
-				return (bytes / (1024 * 1024)).toFixed(2) + 'MB'
+			loadCustomerData() {
+				// 从本地存储获取客户列表
+				const selectedCustomers = uni.getStorageSync('selectedCustomers')
+				if (selectedCustomers) {
+					this.customerList = JSON.parse(selectedCustomers).map(customer => ({
+						...customer,
+						status: 'pending'
+					}))
+				}
 			},
-			async loadOptions() {
-				try {
-					const [groupRes, tagRes] = await Promise.all([
-						getGroupOptions(),
-						getTagOptions()
-					])
-					if (groupRes.code === 200 && groupRes.data) {
-						this.groupOptions = groupRes.data
-					}
-					if (tagRes.code === 200 && tagRes.data) {
-						this.tagOptions = tagRes.data
-					}
-				} catch (e) {
-					console.error('加载选项失败', e)
+			completeCustomer(customer) {
+				// 标记客户为已完成
+				const index = this.customerList.findIndex(item => item.id === customer.id)
+				if (index > -1) {
+					this.customerList[index].status = 'completed'
+					// 更新已完成客户列表
+					this.completedCustomers = this.customerList.filter(item => item.status === 'completed')
 				}
 			},
-			async loadTaskData() {
-				// 加载已有任务数据
+			handlePrev() {
+				uni.navigateBack()
 			},
-			async handleSubmit() {
-				if (!this.formData.title) {
+			handleNext() {
+				if (this.completedCustomers.length === 0) {
 					uni.showToast({
 						icon: 'none',
-						title: '请输入标题'
-					})
-					return
-				}
-				if (!this.formData.groupId) {
-					uni.showToast({
-						icon: 'none',
-						title: '请选择项目分组'
-					})
-					return
-				}
-				if (!this.formData.tagId) {
-					uni.showToast({
-						icon: 'none',
-						title: '请选择项目标签'
-					})
-					return
-				}
-				if (!this.formData.coverImage) {
-					uni.showToast({
-						icon: 'none',
-						title: '请上传封面'
-					})
-					return
-				}
-				if (this.formData.attachments.length === 0) {
-					uni.showToast({
-						icon: 'none',
-						title: '请上传附件'
+						title: '请至少完成一个客户的任务'
 					})
 					return
 				}
 
-				try {
-					uni.showLoading({
-						title: '提交中...'
-					})
-					const res = await submitTask({
-						taskId: this.taskId,
-						...this.formData
-					})
-					uni.hideLoading()
-					if (res.code === 200) {
-						uni.navigateTo({
-							url: '/pages_task/taskCompleteSuccess'
-						})
-					} else {
-						uni.showToast({
-							icon: 'none',
-							title: res.msg || res.message
-						})
-					}
-				} catch (e) {
-					uni.hideLoading()
-					uni.showToast({
-						icon: 'none',
-						title: '提交失败'
-					})
-				}
+				// 保存完成情况到本地存储
+				uni.setStorageSync('completedCustomers', JSON.stringify(this.completedCustomers))
+
+				// 跳转到提交成功页面
+				uni.navigateTo({
+					url: '/pages_task/taskCompleteSuccess'
+				})
 			}
 		}
 	}
@@ -391,288 +165,221 @@
 <style lang="scss" scoped>
 	.container {
 		min-height: 100vh;
-		background: #f5f5f5;
+		background: #F7F8FA;
 		display: flex;
 		flex-direction: column;
-	}
 
-	.status-bar {
-		width: 100%;
-		background: #fff;
-	}
-
-	.header {
-		position: relative;
-		height: 88rpx;
-		display: flex;
-		align-items: center;
-		justify-content: center;
-		background: #fff;
-		border-bottom: 1rpx solid #f0f0f0;
-
-		.back-btn {
+		&::before {
+			content: '';
 			position: absolute;
-			left: 24rpx;
-			width: 40rpx;
-			height: 40rpx;
-
-			image {
-				width: 100%;
-				height: 100%;
-			}
-		}
-
-		.title {
-			font-size: 36rpx;
-			font-weight: bold;
-			color: #333;
-		}
-
-		.header-right {
-			position: absolute;
-			right: 24rpx;
-			display: flex;
-			align-items: center;
-			gap: 16rpx;
-
-			.more-icon {
-				font-size: 32rpx;
-				color: #333;
-			}
+			top: 0;
+			left: 0;
+			right: 0;
+			width: 100%;
+			height: 544rpx;
+			background: linear-gradient(180deg, #E4EFFE 0%, rgba(228, 239, 254, 0) 100%);
 		}
 	}
 
 	.content {
 		flex: 1;
 		padding: 24rpx;
-		padding-bottom: 120rpx;
+		box-sizing: border-box;
+		padding-bottom: 200rpx;
 	}
 
-	.form-section {
-		background: #fff;
-		border-radius: 16rpx;
+	.task-info-section,
+	.complete-section {
+		background-color: #ffffff;
+		border-radius: 24rpx 24rpx 24rpx 24rpx;
 		padding: 24rpx;
 		margin-bottom: 24rpx;
 
-		.form-label {
-			display: flex;
-			align-items: center;
-			margin-bottom: 16rpx;
-			font-size: 28rpx;
-			color: #333;
-
-			.required {
-				color: #FF5030;
-				margin-right: 4rpx;
-			}
+		.section-title {
+			font-size: 32rpx;
+			font-weight: 500;
+			color: #333333;
+			margin-bottom: 24rpx;
 		}
 
-		.form-tips {
-			font-size: 24rpx;
-			color: #999;
+		.info-item {
+			display: flex;
 			margin-bottom: 16rpx;
-		}
-
-		.form-input-wrapper {
-			position: relative;
 
-			.form-input {
-				width: 100%;
-				min-height: 120rpx;
-				padding: 16rpx;
-				background: #f5f5f5;
-				border-radius: 8rpx;
+			.info-label {
 				font-size: 28rpx;
-				color: #333;
+				color: #666666;
+				width: 120rpx;
 			}
 
-			.char-count {
-				position: absolute;
-				right: 16rpx;
-				bottom: 16rpx;
-				font-size: 24rpx;
-				color: #999;
+			.info-value {
+				font-size: 28rpx;
+				color: #333333;
+				flex: 1;
 			}
 		}
 
-		.form-select {
+		.complete-item {
 			display: flex;
-			align-items: center;
 			justify-content: space-between;
-			height: 80rpx;
-			padding: 0 24rpx;
-			background: #f5f5f5;
-			border-radius: 8rpx;
-			font-size: 28rpx;
-			color: #333;
-
-			.placeholder {
-				color: #999;
+			align-items: center;
+			margin-bottom: 24rpx;
+
+			.complete-label {
+				font-size: 28rpx;
+				color: #666666;
 			}
 
-			.arrow-right {
-				font-size: 24rpx;
-				color: #999;
+			.complete-value {
+				font-size: 28rpx;
+				font-weight: 500;
+				color: #388BFF;
 			}
 		}
 
-		.upload-cover {
-			width: 200rpx;
-			height: 200rpx;
-			background: #f5f5f5;
-			border-radius: 8rpx;
-			display: flex;
-			align-items: center;
-			justify-content: center;
+		.progress-bar {
+			width: 100%;
+			height: 12rpx;
+			background-color: #F2F3F5;
+			border-radius: 6rpx;
+			overflow: hidden;
 
-			image {
-				width: 100%;
+			.progress-fill {
 				height: 100%;
-				border-radius: 8rpx;
+				background-color: #388BFF;
+				transition: width 0.3s ease;
 			}
+		}
+	}
 
-			.upload-placeholder {
-				.camera-icon {
-					font-size: 60rpx;
-				}
+	.customer-list {
+		.customer-item {
+			border-radius: 24rpx 24rpx 24rpx 24rpx;
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			padding: 32rpx;
+			margin-bottom: 12rpx;
+			background-color: #ffffff;
+
+			&:last-child {
+				margin-bottom: 0;
 			}
-		}
 
-		.attachment-list {
-			.attachment-item {
+			.left {
 				display: flex;
 				align-items: center;
-				padding: 16rpx;
-				background: #f5f5f5;
-				border-radius: 8rpx;
-				margin-bottom: 16rpx;
-
-				.attachment-icon {
-					font-size: 32rpx;
-					margin-right: 16rpx;
+				flex: 1;
+
+				.head {
+					width: 88rpx;
+					height: 88rpx;
+					border-radius: 50%;
+					margin-right: 24rpx;
 				}
 
-				.attachment-info {
+				.customer-info {
 					flex: 1;
-					display: flex;
-					flex-direction: column;
 
-					.attachment-name {
-						font-size: 28rpx;
-						color: #333;
-						margin-bottom: 4rpx;
-					}
+					.customer-header {
+						display: flex;
+						align-items: center;
+						margin-bottom: 12rpx;
+
+						.customer-name {
+							font-weight: 500;
+							font-size: 32rpx;
+							color: #333333;
+							margin-right: 16rpx;
+						}
+
+						.customer-status {
+							font-size: 24rpx;
+							border-radius: 8rpx;
+							padding: 4rpx 12rpx;
 
-					.attachment-size {
-						font-size: 24rpx;
-						color: #999;
+							&.completed {
+								background: #E6F7EF;
+								color: #00B42A;
+							}
+
+							&.pending {
+								background: #FFF6E5;
+								color: #C89743;
+							}
+						}
 					}
-				}
 
-				.attachment-delete {
-					font-size: 40rpx;
-					color: #999;
-					width: 40rpx;
-					height: 40rpx;
-					display: flex;
-					align-items: center;
-					justify-content: center;
+					.customer-details {
+						display: flex;
+						align-items: center;
+
+						.customer-hospital {
+							font-size: 28rpx;
+							color: #666;
+							margin-right: 24rpx;
+							border-right: 2rpx solid #EAEBEE;
+							padding-right: 24rpx;
+						}
+
+						.customer-department {
+							font-size: 28rpx;
+							color: #666;
+						}
+					}
 				}
 			}
 
-			.add-attachment {
-				display: flex;
-				align-items: center;
-				justify-content: center;
-				padding: 24rpx;
-				background: #E3F2FD;
-				border-radius: 8rpx;
+			.action-btn {
+				background-color: #388BFF;
+				color: #ffffff;
+				padding: 12rpx 24rpx;
+				border-radius: 100rpx;
 				font-size: 28rpx;
-				color: #388BFF;
-
-				.add-icon {
-					font-size: 32rpx;
-					margin-right: 8rpx;
-				}
+				cursor: pointer;
 			}
 		}
 	}
 
-	.submit-btn {
+	.bottom-bar {
 		position: fixed;
 		bottom: 0;
 		left: 0;
 		right: 0;
-		height: 88rpx;
-		background: #388BFF;
-		display: flex;
-		align-items: center;
-		justify-content: center;
-		font-size: 32rpx;
-		color: #fff;
-		font-weight: 500;
-		z-index: 100;
-	}
-
-	.picker-popup {
-		position: fixed;
-		top: 0;
-		left: 0;
-		right: 0;
-		bottom: 0;
-		background: rgba(0, 0, 0, 0.5);
-		z-index: 999;
-		display: flex;
-		align-items: flex-end;
-	}
-
-	.picker-content {
-		width: 100%;
 		background: #fff;
-		border-radius: 24rpx 24rpx 0 0;
+		padding: 24rpx 32rpx;
+		border-top: 1rpx solid #F2F3F5;
+		z-index: 100;
 
-		.picker-header {
+		.action-buttons {
 			display: flex;
-			align-items: center;
 			justify-content: space-between;
-			padding: 24rpx;
-			border-bottom: 1rpx solid #f0f0f0;
 
-			.picker-cancel {
-				font-size: 30rpx;
-				color: #666;
-			}
-
-			.picker-title {
+			.btn {
+				width: 292rpx;
+				height: 88rpx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
 				font-size: 32rpx;
-				font-weight: bold;
-				color: #333;
-			}
-
-			.picker-confirm {
-				font-size: 30rpx;
-				color: #388BFF;
-			}
-		}
-
-		.picker-body {
-			padding: 24rpx;
-			max-height: 600rpx;
-			overflow-y: auto;
+				font-weight: 500;
+				border-radius: 200rpx 200rpx 200rpx 200rpx;
+				cursor: pointer;
 
-			.picker-item {
-				padding: 24rpx 0;
-				font-size: 30rpx;
-				color: #333;
-				border-bottom: 1rpx solid #f0f0f0;
-
-				&:last-child {
-					border-bottom: none;
+				&.btn-cancel {
+					background: #fff;
+					border: 2rpx solid #388BFF;
+					color: #388BFF;
 				}
 
-				&.active {
-					color: #388BFF;
-					font-weight: bold;
+				&.btn-submit {
+					background: #388BFF;
+					color: #fff;
+
+					&:disabled {
+						background: #C8C9CC;
+						cursor: not-allowed;
+					}
 				}
 			}
 		}

+ 155 - 104
pages_task/createTask.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="container">
+		<Watermark  />
 		<Step :step="currentStep" :stepsData="currentText" />
 		<scroll-view class="content" scroll-y>
 			<!-- 驳回意见提示 -->
@@ -105,8 +106,9 @@
 							src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_more.png"></image>
 					</view>
 				</view>
+				<!-- 任务类型目标 - 公开课和问卷调查使用选项列表 -->
 				<view class="form-item"
-					v-if="formData.taskType === '1' || formData.taskType === '8' || formData.taskType === '9'">
+					v-if="formData.taskType === '1' || formData.taskType === '9'">
 					<view class="form-label">
 						<view class="form-option" :class="{ 'selected': item.id == formData.targetId }"
 							v-for="(item, index) in selectionList" :key="index" @click="selectOption(item)">{{
@@ -114,6 +116,21 @@
 							}}</view>
 					</view>
 				</view>
+				
+				<!-- 任务类型目标 - 用药调研使用弹出选择器 -->
+				<view class="form-item"
+					v-if="formData.taskType === '8'">
+					<view class="form-label">
+						<text class="required">*</text>
+						<text>任务类型目标</text>
+					</view>
+					<view class="form-input picker-input" :class="{ placeholder: !formData.targetId }"
+						@click="showPicker('任务类型目标', selectionList)">
+						{{ formData.targetDisplayText || '请选择任务类型目标' }}
+						<image class="icon"
+							src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_more.png"></image>
+					</view>
+				</view>
 
 
 				<view class="form-item">
@@ -238,107 +255,107 @@ export default {
 		EvanSwitch
 	},
 	data() {
-		return {
-			taskTypeDict: [], //任务类型字典
-			taskType: [], //任务类型
-			taskTypeOriginalData: [], //任务类型原始数据(包含dictLabel和dictValue)
-			companyList: [], //归属项目
-			projectData: [], //项目数据(持久化存储)
-			productList: [], //产品列表
-			companyData: [],
-			userInfo: {},
-			showTaskPopup: false,
-			primaryOptions: [{
-				id: 1,
-				name: '中药事业部',
-				children: ['中药一部', '中药二部', '中药三部', '中药四部']
-			},
-			{
-				id: 2,
-				name: '事业1组',
-				children: ['事业1组-项目部', '事业1组-市场部', '事业1组-技术部']
-			},
-
-			],
-			activePrimaryIndex: 0,
-			currentSecondaryOptions: [],
-			selectedSecondaryItem: '',
-			selectedPrimaryItem: null,
-			selectedIndex: -1,
-			selectedProject: null,
-			belongingprojects: [{
-				name: '学术交流项目'
-			},
-			{
-				name: '科学调研项目'
-			},
-			{
-				name: '2026年1月医学研究项目'
-			},
-			{
-				name: '2026年2月医学研究项目'
-			},
-			{
-				name: '2026年3月医学研究项目'
-			}
-			],
-			searchKeyword: '',
-			showBelongingPopup: false,
-			showPickerVisible: false,
-			costColumns: [
-				['主体1', '主体2', '主体3'],
-			],
-			taskTypeColumns: [
-				// ['类型1', '类型2', '类型3'],
-			],
-			currentStep: 1,
-			currentText: [{
-				id: 1,
-				stepNumber: 1,
-				title: '填写任务'
-			},
-			{
-				id: 2,
-				stepNumber: 2,
-				title: '选择客户'
-			},
-			{
-				id: 3,
-				stepNumber: 3,
-				title: '积分设置'
-			}
-			],
-			rejectionInfo: '',
-			formData: {
-				costShareId: '',
-				planStartTime: '',
-				planEndTime: '',
-				belongType: '',
-				deptId: '',
-				projectId: '',
-				productId: '',
-				taskType: '',
-				targetId: '',
-				taskTypeId: '',
-				// companyUserId: '',
-				addRemark: false,
-				remark: '',
-				taskTypeDisplayText: '',
-				belongTypeDisplayText: ''
-
-			},
-			selectedType: null,
-			originalCompanyData: null,
-			pickerTitle: '默认标题',
-			pickerData: [],
-			companyId: '',
-			showStartTimePicker: false,
-			showEndTimePicker: false,
-			startTimeValue: new Date(),
-			endTimeValue: new Date(),
-			selectionList: [], //任务类型选项
+			return {
+				taskTypeDict: [], //任务类型字典
+				taskType: [], //任务类型
+				taskTypeOriginalData: [], //任务类型原始数据(包含dictLabel和dictValue)
+				companyList: [], //归属项目
+				projectData: [], //项目数据(持久化存储)
+				productList: [], //产品列表
+				companyData: [],
+				userInfo: {},
+				showTaskPopup: false,
+				primaryOptions: [{
+					id: 1,
+					name: '中药事业部',
+					children: ['中药一部', '中药二部', '中药三部', '中药四部']
+				},
+				{
+					id: 2,
+					name: '事业1组',
+					children: ['事业1组-项目部', '事业1组-市场部', '事业1组-技术部']
+				},
+
+				],
+				activePrimaryIndex: 0,
+				currentSecondaryOptions: [],
+				selectedSecondaryItem: '',
+				selectedPrimaryItem: null,
+				selectedIndex: -1,
+				selectedProject: null,
+				belongingprojects: [{
+					name: '学术交流项目'
+				},
+				{
+					name: '科学调研项目'
+				},
+				{
+					name: '2026年1月医学研究项目'
+				},
+				{
+					name: '2026年2月医学研究项目'
+				},
+				{
+					name: '2026年3月医学研究项目'
+				}
+				],
+				searchKeyword: '',
+				showBelongingPopup: false,
+				showPickerVisible: false,
+				costColumns: [
+					['主体1', '主体2', '主体3'],
+				],
+				taskTypeColumns: [
+					// ['类型1', '类型2', '类型3'],
+				],
+				currentStep: 1,
+				currentText: [{
+					id: 1,
+					stepNumber: 1,
+					title: '填写任务'
+				},
+				{
+					id: 2,
+					stepNumber: 2,
+					title: '选择客户'
+				},
+				{
+					id: 3,
+					stepNumber: 3,
+					title: '积分设置'
+				}
+				],
+				rejectionInfo: '',
+				formData: {
+					costShareId: '',
+					planStartTime: '',
+					planEndTime: '',
+					belongType: '',
+					deptId: '',
+					projectId: '',
+					productId: '',
+					taskType: '',
+					targetId: '',
+					taskTypeId: '',
+					// companyUserId: '',
+					addRemark: false,
+					remark: '',
+					taskTypeDisplayText: '',
+					belongTypeDisplayText: ''
+
+				},
+				selectedType: null,
+				originalCompanyData: null,
+				pickerTitle: '默认标题',
+				pickerData: [],
+				companyId: '',
+				showStartTimePicker: false,
+				showEndTimePicker: false,
+				startTimeValue: Date.now(), // 使用时间戳而不是Date对象
+				endTimeValue: Date.now(), // 使用时间戳而不是Date对象
+				selectionList: [], //任务类型选项
 
-		}
+			}
 	},
 
 	onLoad: async function (options) {
@@ -363,6 +380,7 @@ export default {
 		// this.formData.planEndTime = this.formatDateTime(new Date());
 		console.log('this.userInfo.companyId:', this.userInfo.companyId)
 		this.getTaskLiveList()//获取公开课选项
+
 	},
 
 	computed: {
@@ -425,8 +443,6 @@ export default {
 	methods: {
 		selectOption(item) {
 			this.formData.targetId = item.id
-			console.log('选择选项:', item)
-			console.log('选择选项sss:', this.formData.targetId)
 		},
 		// 获取用药调研选项
 		getDrugResearchList() {
@@ -604,7 +620,8 @@ export default {
 					})
 					// 调用company接口获取公司项目设置列表
 					// this.companyId
-					company(this.userInfo.userId).then(companyRes => {
+
+					company(this.userInfo.companyId).then(companyRes => {
 						uni.hideLoading()
 						if (companyRes.code === 200) {
 							// 处理公司项目设置列表数据
@@ -703,6 +720,9 @@ export default {
 				// 使用处理后的taskTypeColumns作为数据
 				data = this.taskTypeColumns;
 				console.log('任务类型数据:', data);
+			} else if (title === '任务类型目标') {
+				// 任务类型目标数据使用传入的selectionList
+				console.log('任务类型目标数据:', data);
 			} else if (title === '归属类型') {
 				// 归属类型数据已经在onLoad中获取
 				data = this.belongTypeList;
@@ -742,6 +762,11 @@ export default {
 				this.pickerData = [data.map(item => item.nickName)]
 				// 保存原始数据,用于后续获取userId
 				this.originalCompanyData = data
+			} else if (title === '任务类型目标' && data && data.length > 0) {
+				// 处理任务类型目标数据,将title作为显示文本
+				this.pickerData = [data.map(item => item.title)]
+				// 保存原始数据,用于后续获取id
+				this.originalCompanyData = data
 			} else {
 				this.pickerData = data
 				this.originalCompanyData = null
@@ -852,6 +877,22 @@ export default {
 					} else {
 						console.log('未找到对应的归属类型');
 					}
+				} else if (this.pickerTitle === '任务类型目标' && this.originalCompanyData) {
+					// e.value[0]是选中的文本值(title)
+					const selectedTitle = e.value[0];
+					console.log('选中的任务类型目标文本:', selectedTitle);
+					console.log('originalCompanyData:', this.originalCompanyData);
+					// 从originalCompanyData中找到对应的项
+					const selectedItem = this.originalCompanyData.find(item => item.title === selectedTitle);
+					if (selectedItem) {
+						// 保存id到表单的targetId字段
+						this.formData.targetId = selectedItem.id;
+						// 保存显示文本
+						this.formData.targetDisplayText = selectedTitle;
+						console.log('设置formData.targetId为:', selectedItem.id);
+					} else {
+						console.log('未找到对应的任务类型目标');
+					}
 				}
 				//  else if (this.pickerTitle === '业务员' && this.originalCompanyData) {
 				// 	// e.value[0]是选中的文本值(nickName)
@@ -992,6 +1033,16 @@ export default {
 			const minutes = String(date.getMinutes()).padStart(2, '0');
 			const seconds = String(date.getSeconds()).padStart(2, '0');
 			return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+		},
+		openStartTimePicker() {
+			// 重置开始时间为当前时间(使用时间戳)
+			this.startTimeValue = Date.now();
+			this.showStartTimePicker = true;
+		},
+		openEndTimePicker() {
+			// 重置结束时间为当前时间(使用时间戳)
+			this.endTimeValue = Date.now();
+			this.showEndTimePicker = true;
 		}
 	}
 }

+ 248 - 521
pages_task/editSelectCustomer.vue

@@ -1,99 +1,49 @@
 <template>
 	<view class="container">
+		<Watermark  />
 		<Step :step="currentStep" :stepsData="currentText" />
 
 		<scroll-view class="content" scroll-y>
-			<!-- 客户积分设置列表 -->
-			<view class="integral-section">
-				<view class="section-header">
-					<view class="section-title">客户姓名</view>
-					<view class="section-subtitle">积分数值</view>
+			<!-- 搜索栏 -->
+			<view class="search-section">
+				<view class="search-input-wrapper">
+					<image class="search-icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_search.png"></image>
+					<input class="search-input" type="text" placeholder="输入客户名称" v-model="searchKeyword"
+						@input="handleSearch" />
+					<image class="clear-icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_clear.png" v-if="searchKeyword"
+						@click="clearSearch"></image>
 				</view>
-
-				<view class="integral-list">
-					<view class="integral-item" v-for="(customer, index) in customerList" :key="customer.id">
-						<view class="customer-info">
-							<view class="customer-name">{{ customer.doctorName }}</view>
-						</view>
-						<view class="integral-input-wrapper">
-							<input class="integral-input" type="number" :placeholder="customer.placeholder"
-								v-model="customer.integral" :disabled="customer.disabled"
-								@input="onIntegralInput(customer)" />
-							<view v-if="customer.integral" class="clear-icon-wrapper"
-								@click.stop="clearIntegral(customer)">
-								<image class="clear-icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_clear.png"></image>
-							</view>
-						</view>
+				<view class="section-title">已选择 {{ selectedCustomers.length||'0' }} 人:</view>
+				<view class="selected-tags">
+					<view class="selected-tag" v-for="(customer, index) in selectedCustomers" :key="customer.id">
+						<text class="tag-name">{{ customer.doctorName||'-' }}</text>
+						<text class="tag-remove" @click="removeCustomer(customer.id)">×</text>
 					</view>
 				</view>
 			</view>
-		</scroll-view>
 
-
-		<!-- 概览弹窗 -->
-		<!-- :show="showOverview" -->
-		<u-popup :show="showOverview" mode="bottom" @close="closeOverviewPopup" round="20" :safeAreaInsetBottom="true">
-			<view class="overview-popup">
-				<!-- 弹窗头部 -->
-				<view class="popup-header">
-					<text class="popup-title">概览</text>
-					<view class="close-btn" @click="closeOverviewPopup">
-						<image class="close-icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_close.png"></image>
-					</view>
-				</view>
-
-				<!-- 任务信息 -->
-				<view class="overview-section">
-					<view class="row">
-						<text class="line"></text>
-						<view class="section-title">任务信息</view>
-					</view>
-					<view class="info-list">
-						<view class="info-item">
-							<view class="info-label">项目归属:</view>
-							<view class="info-value">湖南省药学服务公司</view>
-						</view>
-						<view class="info-item">
-							<view class="info-label">项目任务:</view>
-							<view class="info-value">科普文章</view>
-						</view>
-						<view class="info-item">
-							<view class="info-label">项目时间:</view>
-							<view class="info-value">2025/11/19 14:12~2025/11/19 14:12</view>
-						</view>
-					</view>
-				</view>
-
-				<!-- 客户信息 -->
-				<view class="overview-section">
-					<view class="row">
-						<text class="line"></text>
-						<view class="section-title">客户信息</view>
-					</view>
-					<view class="customer-table">
-						<!-- 表头 -->
-						<view class="table-header">
-							<view class="table-cell" style="flex: 1.5;">姓名</view>
-							<view class="table-cell" style="flex: 1;">级别</view>
-							<view class="table-cell" style="flex: 1;">积分</view>
-							<view class="table-cell" style="flex: 2;">联系方式</view>
-						</view>
-
-						<!-- 表格内容 -->
-						<view class="table-body">
-							<view class="table-row" v-for="(customer, index) in customerList" :key="customer.id">
-								<view class="table-cell" style="flex: 1.5;">{{ customer.doctorName }}</view>
-								<view class="table-cell" style="flex: 1;">一级</view>
-								<view class="table-cell" style="flex: 1;">{{ customer.integral || '0' }}</view>
-								<view class="table-cell" style="flex: 2;">177****4235</view>
+			<!-- 客户列表 -->
+			<view class="customer-list">
+				<view class="customer-item" :class="{ active: isSelected(customer.id) }"
+					v-for="(customer, index) in filteredCustomers" :key="customer.id" @click="toggleCustomer(customer)">
+					<view class="left">
+						<image class="head" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/my_heads_icon.png"></image>
+						<view class="customer-info">
+							<view class="customer-header">
+								<view class="customer-name">{{ customer.doctorName ||'-'}}</view>
+								<view class="customer-level" v-if="customer.jobTitle">{{ customer.jobTitle }}</view>
+							</view>
+							<view class="customer-details">
+								<view class="customer-hospital">{{ customer.cityName||'-' }}</view>
+								<view class="customer-department">{{ customer.department ||'-'}}</view>
 							</view>
 						</view>
 					</view>
+					<checkbox :value="customer.id" :checked="isSelected(customer.id)" @click.stop="toggleCustomer(customer)"
+						color="#388BFF" />
 				</view>
-				<!-- 安全区域占位 -->
-				<view class="safe-area"></view>
 			</view>
-		</u-popup>
+		</scroll-view>
 
 		<!-- 底部操作栏 -->
 		<view class="bottom-bar">
@@ -103,86 +53,73 @@
 			</view>
 			<view class="action-buttons">
 				<view class="btn btn-cancel" @click="handlePrev">上一步</view>
-				<view class="btn btn-submit" @click="submit">提交</view>
+				<view class="btn btn-submit" @click="handleNext">下一步</view>
 			</view>
 		</view>
 	</view>
 </template>
 
 <script>
-	import { speakerList } from '@/api/speaker.js'
-import{editAudit} from '@/api/task.js'
+import { getAppliedList } from '@/api/task.js'
 	import Step from '@/pages_task/components/step.vue'
 	export default {
 		components: {
 			Step
 		},
 		data() {
-				return {
-					currentText: [{
-							id: 1,
-							stepNumber: 1,
-							title: '填写任务'
-						},
-							{
-							id: 2,
-							stepNumber: 2,
-							title: '积分设置'
-						}
-					],
-					currentStep: 2,
-					showOverview: false, // 控制概览弹窗显示
-					customerList: [],
-					doctorId: '',
-					fillTaskFormData: {} // 存储从 fillTask.vue 页面传递的表单数据
-				}
-			},
-		onLoad: function(options) {
-			console.log("编辑任务积分接受数据",options);
-			if (options.doctorId) {
-				this.doctorId = options.doctorId;
-				
-			} 
-			// 从本地存储中获取 fillTask.vue 页面传递的表单数据
-			const fillTaskFormDataStr = uni.getStorageSync('fillTaskFormData');
-			if (fillTaskFormDataStr) {
-				this.fillTaskFormData = JSON.parse(fillTaskFormDataStr);
-				console.log('获取到 fillTask 表单数据:', this.fillTaskFormData);
+			return {
+				currentText: [{
+						id: 1,
+						stepNumber: 1,
+						title: '编辑任务'
+					},
+					{
+						id: 2,
+						stepNumber: 2,
+						title: '选择客户'
+					},
+					{
+						id: 3,
+						stepNumber: 3,
+						title: '积分设置'
+					}
+				],
+				currentStep: 2,
+				searchKeyword: '',
+				selectedCustomers: [],
+				customerList: [],
+				loading: false,
+				debounceTimer: null
 			}
+		},
+		onLoad() {
 			this.loadCustomerData()
-
+			this.loadSelectedCustomers()
 		},
 		computed: {
-			totalIntegral() {
-				let total = 0
-				this.customerList.forEach(customer => {
-					const integral = parseInt(customer.integral) || 0
-					total += integral
-				})
-				return total
+			filteredCustomers() {
+				if (!this.searchKeyword.trim()) {
+					return this.customerList
+				}
+				const keyword = this.searchKeyword.toLowerCase()
+				return this.customerList.filter(customer =>
+					(customer.doctorName && customer.doctorName.toLowerCase().includes(keyword)) ||
+					(customer.cityName && customer.cityName.toLowerCase().includes(keyword)) ||
+					(customer.department && customer.department.toLowerCase().includes(keyword))
+				)
 			}
 		},
 		methods: {
-		
 			async loadCustomerData() {
 				try {
 					this.loading = true
-					// 调用speakerList接口获取数据
-					const res = await speakerList({})
+					let companyId=uni.getStorageSync('userInfo').companyId
+					
+					// getAppliedList 查询到 定义审核通过了的医生
+					const res = await getAppliedList(companyId)
 					if (res.code === 200 && res.rows) {
 						// 将接口返回的数据映射为页面需要的格式
-						this.customerList = res.rows.map(item => ({
-							id: item.id,
-							doctorName: item.doctorName,
-							integral: '',
-							placeholder: '请输入积分',
-							disabled: false
-						}));
-						
-						// 如果有 doctorId 参数,只显示对应 ID 的医生
-						if (this.doctorId) {
-							this.customerList = this.customerList.filter(item => item.id == this.doctorId);
-						}
+						this.customerList = res.rows;
 					}
 				} catch (error) {
 					console.error('获取客户数据失败:', error)
@@ -194,171 +131,98 @@ import{editAudit} from '@/api/task.js'
 					this.loading = false
 				}
 			},
-			// 根据 doctorId 获取客户信息
-			getCustomerInfo(doctorId) {
-				// 这里应该调用接口获取客户信息
-				// 暂时使用模拟数据
-				this.customerList = [{
-						id: doctorId,
-						doctorName: '客户' + doctorId,
-						integral: '',
-						placeholder: '请输入积分',
-						disabled: false
-				}];
+			loadSelectedCustomers() {
+				// 从本地存储获取已选择的客户
+				const selectedCustomers = uni.getStorageSync('editSelectedCustomers')
+				if (selectedCustomers) {
+					this.selectedCustomers = JSON.parse(selectedCustomers)
+				}
 			},
-			
-			
-			// 显示概览弹窗
-			showOverviewPopup() {
-				this.showOverview = true
+			handleSearch() {
+				// 清除之前的定时器
+				if (this.debounceTimer) {
+					clearTimeout(this.debounceTimer)
+				}
+				// 设置新的定时器,500毫秒后执行搜索
+				this.debounceTimer = setTimeout(() => {
+					// 搜索逻辑已经在computed中处理,这里可以添加额外的搜索逻辑
+					console.log('执行搜索:', this.searchKeyword)
+				}, 500)
 			},
-
-			// 关闭概览弹窗
-			closeOverviewPopup() {
-				this.showOverview = false
+			clearSearch() {
+				this.searchKeyword = ''
 			},
-
-			clearIntegral(customer) {
-				// 使用 $set 确保响应式更新
-				this.$set(customer, 'integral', '')
+			isSelected(customerId) {
+				return this.selectedCustomers.some(customer => customer.id === customerId)
 			},
-			onIntegralInput(customer) {
-				// 积分输入验证
-				if (customer.integral && parseInt(customer.integral) < 0) {
-					this.$set(customer, 'integral', '0')
+			toggleCustomer(customer) {
+				const index = this.selectedCustomers.findIndex(item => item.id === customer.id)
+				if (index > -1) {
+					// 已选中,移除
+					this.selectedCustomers.splice(index, 1)
+				} else {
+					// 未选中,添加
+					this.selectedCustomers.push(customer)
+				}
+			},
+			removeCustomer(customerId) {
+				const index = this.selectedCustomers.findIndex(item => item.id === customerId)
+				if (index > -1) {
+					this.selectedCustomers.splice(index, 1)
 				}
 			},
-			handlePrev() {
-					uni.navigateBack()
-				},
-				submit() {
-					// 验证所有客户积分是否已填写
-					const emptyCustomers = this.customerList.filter(customer => !customer.integral || customer.integral === '')
-					if (emptyCustomers.length > 0) {
-						uni.showToast({
-							icon: 'none',
-							title: '请为所有客户设置积分'
-						})
-						return
-					}
-
-					// 验证积分是否为数字
-					const invalidCustomers = this.customerList.filter(customer => {
-						const integral = parseInt(customer.integral)
-						return isNaN(integral) || integral < 0
-					})
-
-					if (invalidCustomers.length > 0) {
-						uni.showToast({
-							icon: 'none',
-							title: '请输入有效的积分数值'
-						})
-						return
-					}
-					// 获取用户信息
-					const userInfoStr = uni.getStorageSync('userInfo')
-					const userInfo = userInfoStr ? JSON.parse(userInfoStr) : {}
-
-					// 构建提交数据
-					const taskFormData = this.fillTaskFormData
-					const taskData = {
-						// 任务基本信息
-						id: taskFormData.id || 0,
-						taskNo: taskFormData.taskNo || '',
-						taskName: taskFormData.taskName || '',
-						deptId: taskFormData.deptId || 0,
-						projectId: taskFormData.projectId || 0,
-						costShareId: taskFormData.costShareId || 0,
-						taskType: taskFormData.taskType || 0,
-						taskIntegral: this.totalIntegral || 0,
-						taskCount: taskFormData.taskCount || 0,
-						taskUnit: taskFormData.taskUnit || 0,
-						taskStatus: taskFormData.taskStatus || 0,
-						productId: taskFormData.productId || 0,
-						doctorId: this.doctorId || 0,
-						planStartTime: taskFormData.planStartTime || '',
-						planEndTime: taskFormData.planEndTime || '',
-						applyTime: taskFormData.applyTime || '',
-						serviceConfirmStatus: taskFormData.serviceConfirmStatus || 0,
-						finishStatus: taskFormData.finishStatus || 0,
-						belongType: taskFormData.belongType || 0,
-						isSpotCheck: taskFormData.isSpotCheck || 0,
-						spotCheckUserId: taskFormData.spotCheckUserId || 0,
-						spotCheckTime: taskFormData.spotCheckTime || '',
-						auditStatus: taskFormData.auditStatus || 0,
-						companyId: userInfo.companyId || 0,
-						companyUserId: userInfo.id || 0
-					}
-					// deptId: taskFormData.deptId || 0,
-					// 	projectId: taskFormData.projectId || 0,
-					// 	costShareId: taskFormData.costShareId || 0,
-					// 	taskType: taskFormData.taskType || 0,
-					// 	taskIntegral: this.totalIntegral || 0,
-					// 	taskUnit: taskFormData.taskUnit || 0,
-					// 	productId: taskFormData.productId || 0,
-					// 	planStartTime: taskFormData.planStartTime || '',
-					// 	planEndTime: taskFormData.planEndTime || '',
-					// 	belongType: taskFormData.belongType || 0,
-					// 	companyId: userInfo.companyId || 0,
-					// 	companyUserId: userInfo.id || 0,
-					// 	doctorId: this.doctorId || 0,
-
-					console.log('提交的任务数据:', taskData)
-
-					// 调用addInfo接口提交表单
-					uni.showLoading({
-						title: '提交中...'
-					})
-					editAudit(taskData).then(res => {
-						uni.hideLoading()
-						if (res.code === 200) {
-							// 清除本地存储的表单数据
-							uni.removeStorageSync('fillTaskFormData');
-							// 显示提交成功提示
-							uni.showToast({
-								title: '任务创建成功',
-								success: () => {
-									// 延迟跳转,让用户看到成功提示
-									setTimeout(() => {
-										uni.navigateTo({
-											url: '/pages_task/taskList'
-										})
-									}, 1500)
-								}
-							})
-						} else {
-							uni.showToast({
-								icon: 'none',
-								title:res.msg|| res.message || '提交失败'
-							})
-						}
-					}).catch(err => {
-						uni.hideLoading()
-						uni.showToast({
-							icon: 'none',
-							title: '网络错误,请重试'
-						})
-					})
-				},
 			deleteSelected() {
-				// 删除所有客户数据
+				if (this.selectedCustomers.length === 0) {
+					uni.showToast({
+						icon: 'none',
+						title: '请先选择要删除的客户'
+					})
+					return
+				}
+				
+				// 这里可以添加删除逻辑,比如从列表中移除已选中的客户
 				uni.showModal({
 					title: '提示',
-					content: '确定要删除所有客户数据吗?删除后不可恢复。',
+					content: `确定要删除选中的 ${this.selectedCustomers.length} 个客户吗?`,
 					success: (res) => {
 						if (res.confirm) {
-							// 清空所有客户的积分数据
-							this.customerList.forEach(customer => {
-								this.$set(customer, 'integral', '')
-							})
-
+							// 从客户列表中移除已选中的客户
+							const selectedIds = this.selectedCustomers.map(item => item.id)
+							this.customerList = this.customerList.filter(
+								customer => !selectedIds.includes(customer.id)
+							)
+							// 清空已选中的客户
+							this.selectedCustomers = []
 							uni.showToast({
-								title: '已清空所有客户积分',
-								icon: 'success'
+								title: '删除成功'
 							})
 						}
 					}
 				})
+			},
+			handlePrev() {
+				uni.navigateBack()
+			},
+			handleNext() {
+				if (this.selectedCustomers.length === 0) {
+					uni.showToast({
+						icon: 'none',
+						title: '请至少选择一个客户'
+					})
+					return
+				}
+
+				// 保存选中的客户到本地存储,以便pointsSettings.vue获取
+				const enhanced = this.selectedCustomers.map(item => ({
+					...item,
+					mobile: item.mobile||''
+				}))
+				uni.setStorageSync('editSelectedCustomers', JSON.stringify(enhanced))
+
+				// 跳转到下一步(积分设置)
+				uni.navigateTo({
+					url: '/pages_task/pointsSettings'
+				})
 			}
 		}
 	}
@@ -388,281 +252,156 @@ import{editAudit} from '@/api/task.js'
 		padding: 24rpx;
 		box-sizing: border-box;
 		padding-bottom: 200rpx;
-		position: relative;
 	}
 
-	.integral-section {
+	.search-section {
 		background-color: #ffffff;
-		border-radius: 24rpx;
-		padding: 32rpx 24rpx;
+		border-radius: 24rpx 24rpx 24rpx 24rpx;
+		padding: 24rpx;
 		margin-bottom: 24rpx;
 
-		.section-header {
-			display: flex;
-			justify-content: space-between;
-			align-items: center;
-			margin-bottom: 32rpx;
-			padding: 32rpx 0;
-			background: #F5F9FF;
-			border-radius: 16rpx;
-			font-size: 28rpx;
-			color: #666666;
-			text-align: center;
-			font-weight: 600;
-
-			.section-title {
-				flex: 1;
-			}
-
-			.section-subtitle {
-				flex: 1;
-			}
+		.section-title {
+			font-size: 24rpx;
+			color: #999999;
+			margin-bottom: 24rpx;
 		}
 
-		.integral-list {
-			.integral-item {
+		.selected-tags {
+			display: flex;
+			flex-wrap: wrap;
+			gap: 16rpx;
+
+			.selected-tag {
 				display: flex;
-				justify-content: space-between;
 				align-items: center;
-				padding: 32rpx 0;
-				border-bottom: 1rpx solid #F2F3F5;
+				border-radius: 76rpx 76rpx 76rpx 76rpx;
+				border: 2rpx solid #F5F5F5;
+				padding: 12rpx 24rpx;
+				font-size: 28rpx;
 
-				&:last-child {
-					border-bottom: none;
+				.tag-name {
+					color: #333;
+					margin-right: 8rpx;
 				}
 
-				.customer-info {
-					flex: 1;
-					text-align: center;
-
-					.customer-name {
-						font-size: 32rpx;
-						font-weight: 500;
-						color: #333333;
-					}
-				}
-
-				.integral-input-wrapper {
-					flex: 1;
-					display: flex;
-					align-items: center;
-					justify-content: center;
-					position: relative;
-
-					.integral-input {
-						width: 100%;
-						font-size: 32rpx;
-						color: #333333;
-						text-align: center;
-						padding: 12rpx 60rpx 12rpx 16rpx;
-						background: #F7F8FA;
-						border-radius: 8rpx;
-
-						&::placeholder {
-							color: #C8C9CC;
-							font-size: 28rpx;
-							text-align: center;
-						}
-
-						&:disabled {
-							background: transparent;
-							opacity: 0.8;
-						}
-					}
-
-					.clear-icon-wrapper {
-						position: absolute;
-						right: 8rpx;
-						width: 48rpx;
-						height: 48rpx;
-						display: flex;
-						align-items: center;
-						justify-content: center;
-						z-index: 10;
-						cursor: pointer;
-
-						&:active {
-							opacity: 0.6;
-						}
-
-						.clear-icon {
-							width: 28rpx;
-							height: 28rpx;
-						}
-					}
+				.tag-remove {
+					color: #C8C9CC;
+					font-size: 36rpx;
+					line-height: 1;
+					cursor: pointer;
 				}
 			}
 		}
-	}
-
-	/* 概览弹窗样式 */
-	.overview-popup {
-		background-color: #fff;
-		border-radius: 32rpx 32rpx 0 0;
-		max-height: 80vh;
-		overflow-y: auto;
-		padding-bottom: env(safe-area-inset-bottom);
-	}
 
-	.popup-header {
-		display: flex;
-		justify-content: center;
-		align-items: center;
-		padding: 32rpx 40rpx;
-		.popup-title {
-			font-weight: 500;
-			font-size: 32rpx;
-			color: #333333;
-			
-		}
-
-		.close-btn {
-			width: 48rpx;
-			height: 48rpx;
+		.search-input-wrapper {
+			background: #F7F8FA;
+			border-radius: 38rpx 38rpx 38rpx 38rpx;
+			position: relative;
 			display: flex;
 			align-items: center;
-			justify-content: center;
-			cursor: pointer;
-			position: absolute;
-			right: 0;
+			padding: 0 28rpx;
+			height: 72rpx;
+			margin-bottom: 24rpx;
 
-			.close-icon {
-				width: 44rpx;
-				height: 44rpx;
-				margin-right: 32rpx;
-				flex-shrink: 0;
+			.search-icon {
+				width: 36rpx;
+				height: 36rpx;
+				margin-right: 16rpx;
 			}
 
-			&:active {
-				opacity: 0.6;
+			.search-input {
+				flex: 1;
+				height: 100%;
+				font-size: 28rpx;
+				color: #333;
+			}
+
+			.clear-icon {
+				width: 32rpx;
+				height: 32rpx;
+				margin-left: 16rpx;
 			}
 		}
 	}
 
-	.overview-section {
-		padding: 32rpx 40rpx;
-
-		.row {
+	.customer-list {
+		.customer-item {
+			border-radius: 24rpx 24rpx 24rpx 24rpx;
 			display: flex;
 			align-items: center;
-			margin-bottom: 24rpx;
-
-			&:last-child {
-				border-bottom: none;
-			}
+			justify-content: space-between;
+			padding: 32rpx;
+			margin-bottom: 12rpx;
+			background-color: #ffffff;
+			cursor: pointer;
+			transition: all 0.3s;
 
-			.line {
-				width: 6rpx;
-				height: 32rpx;
-				background: #388BFF;
-				border-radius: 36rpx;
-				margin-right: 20rpx;
+			&.active {
+				background: rgba(56,139,255,0.06);
 			}
 
-			.section-title {
-				font-size: 28rpx;
-				font-weight: 600;
-				color: #333333;
+			&:last-child {
+				margin-bottom: 0;
 			}
-		}
-
-
 
-
-
-		.info-list {
-			.info-item {
+			.left {
 				display: flex;
 				align-items: center;
-				margin-bottom: 16rpx;
 
-				.info-label {
-					color: #999999;
-					flex-shrink: 0;
-					width: 140rpx;
+				.head {
+					width: 88rpx;
+					height: 88rpx;
+					border-radius: 50%;
+					margin-right: 24rpx;
 				}
 
-				.info-value {
-					color: #333333;
+				.customer-info {
 					flex: 1;
-					line-height: 1.4;
-				}
-			}
-		}
 
-		.customer-table {
-			.table-header {
-				display: flex;
-				background: #F5F9FF;
-				border-radius: 8rpx;
-				padding: 20rpx 16rpx;
-				margin-bottom: 8rpx;
-
-				.table-cell {
-					font-size: 24rpx;
-					font-weight: 600;
-					color: #666666;
-					text-align: center;
-				}
-			}
+					.customer-header {
+						display: flex;
+						align-items: center;
+						margin-bottom: 12rpx;
 
-			.table-body {
-				.table-row {
-					display: flex;
-					padding: 20rpx 16rpx;
-					border-bottom: 1rpx solid #F2F3F5;
+						.customer-name {
+							font-weight: 500;
+							font-size: 32rpx;
+							color: #333333;
+							margin-right: 16rpx;
+						}
 
-					&:last-child {
-						border-bottom: none;
+						.customer-level {
+							font-size: 24rpx;
+							color: #C89743;
+							background: #FFF6E5;
+							border-radius: 8rpx;
+							padding: 4rpx 12rpx;
+						}
 					}
 
-					.table-cell {
-						font-size: 28rpx;
-						color: #333333;
-						text-align: center;
+					.customer-details {
+						display: flex;
+						align-items: center;
 
-						&:first-child {
-							font-weight: 500;
+						.customer-hospital {
+							font-size: 28rpx;
+							color: #666;
+							margin-right: 24rpx;
+							border-right: 2rpx solid #EAEBEE;
+							padding-right: 24rpx;
+						}
+
+						.customer-department {
+							font-size: 28rpx;
+							color: #666;
 						}
 					}
 				}
 			}
-		}
-	}
 
-	.total-section {
-		padding: 32rpx 40rpx;
-		background: #F5F9FF;
-		border-radius: 16rpx;
-		margin: 24rpx 40rpx 40rpx;
-
-		.total-item {
-			display: flex;
-			justify-content: space-between;
-			align-items: center;
-			margin-bottom: 16rpx;
-
-			&:last-child {
-				margin-bottom: 0;
-			}
-
-			.total-label {
-				font-size: 28rpx;
-				color: #666666;
-			}
-
-			.total-value {
-				font-size: 28rpx;
-				font-weight: 600;
-				color: #388BFF;
-			}
 		}
 	}
 
-	.safe-area {
-		height: env(safe-area-inset-bottom);
-	}
-
 	.bottom-bar {
 		position: fixed;
 		bottom: 0;
@@ -683,10 +422,6 @@ import{editAudit} from '@/api/task.js'
 			color: #666666;
 			margin-right: 32rpx;
 			cursor: pointer;
-
-			&:active {
-				opacity: 0.6;
-			}
 		}
 
 		.action-buttons {
@@ -718,12 +453,4 @@ import{editAudit} from '@/api/task.js'
 			}
 		}
 	}
-
-	.w40 {
-		width: 40rpx;
-	}
-
-	.h40 {
-		height: 40rpx;
-	}
 </style>

+ 1 - 0
pages_task/fillTask.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="container">
+		<Watermark  />
 		<Step :step="currentStep" :stepsData="currentText" />
 		<scroll-view class="content" scroll-y>
 			<!-- 驳回意见提示 -->

+ 1 - 0
pages_task/index.vue

@@ -1,5 +1,6 @@
 <template>
 	<view>
+		<Watermark  />
 		<view class="top-content">
 			<!-- 搜索框 -->
 			<view class="search-cont">

+ 1 - 0
pages_task/pointsSettings.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="container">
+		<Watermark  />
 		<Step :step="currentStep" :stepsData="currentText" />
 
 		<scroll-view class="content" scroll-y>

+ 1 - 1
pages_task/science.vue

@@ -1,6 +1,6 @@
 <template>
 	<view class="container">
-		
+		<Watermark  />
 		<!-- 筛选标签栏 -->
 		<view class="filter-bar">
 			<view class="filter-tabs">

+ 1 - 0
pages_task/selectCustomer.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="container">
+		<Watermark  />
 		<Step :step="currentStep" :stepsData="currentText" />
 
 		<scroll-view class="content" scroll-y>

+ 1 - 0
pages_task/statistics.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="container">
+		<Watermark  />
 		<!-- 统计类型切换 -->
 		<view class="stat-tabs">
 			<view 

+ 1 - 0
pages_task/success.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="container">
+		<Watermark  />
 		<image class="img" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/img_admitsuccess.png"></image>
 		<view class="title">任务创建申请已提交!</view>
 		<view class="txt">预计1-2个工作日完成审核,请耐心等待</view>

+ 1 - 0
pages_task/taskCompleteSuccess.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="container">
+		<Watermark  />
 		<!-- 状态栏占位 -->
 		<view class="status-bar" :style="{height: statusBarHeight}"></view>
 		

+ 2 - 1
pages_task/taskDetail.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="container">
+		<Watermark  />
 		<view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
 		<view class="top">
 			<image class="return" @click="goBack" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/back_white.png"></image>
@@ -13,7 +14,7 @@
 				</view>
 				<view class="card-meta">
 					<view class="meta-tag">{{ detail.taskTypeName||'-'  }}</view>
-					<view class="meta-id">ID:{{ detail.taskNo||'-' }}</view>
+					<view class="meta-id">ID:{{utils.parseIdCard(detail.taskNo)||'-'  }}</view>
 				</view>
 			</view>
 

+ 9 - 4
pages_task/xlTask.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="container">
+		<Watermark  />
 		<!-- 搜索+筛选栏 -->
 		<view class="top-box">
 			<view class="input-item">
@@ -627,8 +628,8 @@ import { getPendingAuditList } from '@/api/audit.js';
 								auditStatus: this.getAuditStatusText(item.finishAuditStatus),
 								showDelete: true,
 								sealImg: item.taskStatus === 1 ? 'https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/img_finished.png' : 'https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/img_unfinish.png',
-								finishAuditInstanceId: item.finishAuditInstanceId || '-',
-								createAuditInstanceId: item.createAuditInstanceId || '-',
+								finishAuditInstanceId: item.finishAuditInstanceId || '',
+								createAuditInstanceId: item.createAuditInstanceId || '',
 							}));
 							// 如果是加载更多,则追加数据
 							if (this.isLoadingMore) {
@@ -755,13 +756,17 @@ import { getPendingAuditList } from '@/api/audit.js';
 				console.log("跳转到任务详情页",item);
 				// 直接跳转到任务详情页,传递id作为taskId参数
 				let id = ''
+				let createAuditInstanceId = item.createAuditInstanceId || ''
+				let finishAuditInstanceId = item.finishAuditInstanceId || ''
 				if(this.currentTopTab === 'task'){
 					id = item.id
 				}else if(this.currentTopTab === 'audit'){
-					id = item.businessData.taskInfo.id
+					id = item.businessData?.taskInfo?.id || ''
+					createAuditInstanceId = createAuditInstanceId || item.businessData?.taskInfo?.createAuditInstanceId || ''
+					finishAuditInstanceId = finishAuditInstanceId || item.businessData?.taskInfo?.finishAuditInstanceId || ''
 				}
 				uni.navigateTo({
-					url: `/pages_task/taskDetail?taskId=${item.createAuditInstanceId||item.businessData.taskInfo.createAuditInstanceId||''}&taskId2=${item.finishAuditInstanceId||item.businessData.taskInfo.finishAuditInstanceId||''}&id=${id||''}&type=${this.currentTopTab}`
+					url: `/pages_task/taskDetail?taskId=${createAuditInstanceId}&taskId2=${finishAuditInstanceId}&id=${id}&type=${this.currentTopTab}`
 				});
 			},
 			selectSubTab(value) {

+ 1 - 0
pages_user/userInfo.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="container">
+		<Watermark  />
 		<view class="content">
 			<view class="summary-section">
 				<view class="summary-header">

+ 9 - 1
utils/common.js

@@ -178,7 +178,8 @@ var parsePhone=function parsePhone(mobile) {
     return str;
 }
 var parseIdCard=function parseIdCard(idCard) {
-    var str = idCard.substr(0,4)+"****"+idCard.substr(8);
+    if(!idCard) return '****';
+    var str = idCard.substr(0,4)+"****"+idCard.substr(idCard.length-4);
     return str;
 }
 var parsePrice=function parsePrice(price) {
@@ -186,6 +187,12 @@ var parsePrice=function parsePrice(price) {
 	  const priceStr = String(price);
 	  return '*'.repeat(priceStr.length);
 }
+var parseBankCard=function parseBankCard(bankCard) {
+	if(!bankCard) return '****';
+	  const cardStr = String(bankCard);
+	  if(cardStr.length <= 8) return '****';
+	  return cardStr.substr(0,4) + ' **** **** ' + cardStr.substr(cardStr.length-4);
+}
  
 //格式为"1990-01-01"
 var getAge=function getAge(strBirthday){    
@@ -552,6 +559,7 @@ module.exports = {
 		getAge:getAge,
 		parseIdCard:parseIdCard,
 		parsePrice:parsePrice,
+		parseBankCard:parseBankCard,
 		getDict:getDict,
 		addHisSearch:addHisSearch,
 		clearHisSearch:clearHisSearch,