Bläddra i källkod

发单新增图片增删接口

Yannay 2 månader sedan
förälder
incheckning
178f6d4f68

+ 8 - 5
main.js

@@ -4,14 +4,17 @@ import store from './store'
4 4
 // main.js,注意要在use方法之后执行
5 5
 import uView from '@/uni_modules/uview-ui'
6 6
 Vue.use(uView)
7
+
8
+
9
+
7 10
 // 如此配置即可
8 11
 // uni.$u.config.unit = 'rpx'
9 12
 
10 13
 Vue.config.productionTip = false
11 14
 App.mpType = 'app'
12 15
 const app = new Vue({
13
-	store,
14
-    ...App
16
+  store,
17
+  ...App
15 18
 })
16 19
 
17 20
 // http 拦截器,将此部分放在 new Vue() 和 app.$mount() 之间,才能 App.vue 中正常使用
@@ -24,10 +27,10 @@ import { showLoading } from './utils/loading'
24 27
 Vue.use(httpApi, app);
25 28
 
26 29
 import hideNav from "@/utils/hideNav.js";
27
-Vue.use(hideNav,app);
30
+Vue.use(hideNav, app);
28 31
 
29
-Vue.prototype.$getDicts = function (dictType,customFlag = true) {
30
-  return store.dispatch('dict/getDicts', {dictType,customFlag})
32
+Vue.prototype.$getDicts = function (dictType, customFlag = true) {
33
+  return store.dispatch('dict/getDicts', { dictType, customFlag })
31 34
 }
32 35
 
33 36
 // 引入共用的方法

+ 9 - 45
manifest.json

@@ -1,17 +1,14 @@
1 1
 {
2 2
     "name" : "时与",
3
-    "appid" : "__UNI__0C0EF72",
3
+    "appid" : "__UNI__DDAE2E0",
4 4
     "description" : "",
5 5
     "versionName" : "1.2.3",
6 6
     "versionCode" : 123,
7 7
     "transformPx" : false,
8
-    /* 5+App特有相关 */
9 8
     "app-plus" : {
10 9
         "webView" : {
11
-            // 3.5.0 + 仅Android支持
12 10
             "x5" : {
13
-                // 此属性需要勾选 Android X5 Webview 模块,详细参见下面的说明
14
-                "allowDownloadWithoutWiFi" : true // 是否允许用户在非WiFi网络时进行x5内核的下载。默认值false(如果为true,就不会显示用户确认的弹窗。)
11
+                "allowDownloadWithoutWiFi" : true
15 12
             }
16 13
         },
17 14
         "usingComponents" : true,
@@ -19,7 +16,7 @@
19 16
         "compilerVersion" : 3,
20 17
         "runmode" : "liberate",
21 18
         "compatible" : {
22
-            "ignoreVersion" : true //true表示忽略版本检查提示框,HBuilderX1.9.0及以上版本支持  
19
+            "ignoreVersion" : true
23 20
         },
24 21
         "splashscreen" : {
25 22
             "alwaysShowBeforeRender" : true,
@@ -27,9 +24,8 @@
27 24
             "autoclose" : true,
28 25
             "delay" : 0
29 26
         },
30
-        /* 模块配置 */
31 27
         "modules" : {
32
-            "Canvas" : "nvue canvas", //使用Canvas模块
28
+            "Canvas" : "nvue canvas",
33 29
             "Maps" : {},
34 30
             "Bluetooth" : {},
35 31
             "Geolocation" : {},
@@ -37,62 +33,33 @@
37 33
             "VideoPlayer" : {},
38 34
             "Webview-x5" : {}
39 35
         },
40
-        /* 应用发布信息 */
41 36
         "distribute" : {
42
-            /* android打包配置 */
43 37
             "android" : {
44 38
                 "permissions" : [
45 39
                     "<uses-feature android:name=\"android.hardware.camera\"/>",
46 40
                     "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
47
-                    "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
48 41
                     "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
49
-                    "<uses-permission android:name=\"android.permission.ACCESS_LOCATION_EXTRA_COMMANDS\"/>",
50
-                    "<uses-permission android:name=\"android.permission.ACCESS_MOCK_LOCATION\"/>",
51 42
                     "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
52 43
                     "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
53
-                    "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
54 44
                     "<uses-permission android:name=\"android.permission.CAMERA\"/>",
55
-                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
56
-                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
57
-                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
58
-                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
59
-                    "<uses-permission android:name=\"android.permission.GET_TASKS\"/>",
60
-                    "<uses-permission android:name=\"android.permission.INSTALL_SHORTCUT\"/>",
61 45
                     "<uses-permission android:name=\"android.permission.INTERNET\"/>",
62
-                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
63
-                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
64
-                    "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
65 46
                     "<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
66
-                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
67
-                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
68
-                    "<uses-permission android:name=\"android.permission.READ_SMS\"/>",
69
-                    "<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\"/>",
70 47
                     "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
71
-                    "<uses-permission android:name=\"android.permission.SEND_RESPOND_VIA_MESSAGE\"/>",
72
-                    "<uses-permission android:name=\"android.permission.SEND_SMS\"/>",
73
-                    "<uses-permission android:name=\"android.permission.USE_FINGERPRINT\"/>",
74 48
                     "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
75
-                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
76
-                    "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
77 49
                     "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
78
-                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
79
-                    "<uses-permission android:name=\"android.permission.WRITE_SMS\"/>",
80
-                    "<uses-permission android:name=\"android.permission.RECEIVE_USER_PRESENT\"/>",
81 50
                     "<uses-permission android:name=\"android.permission.MANAGE_EXTERNAL_STORAGE\"/>",
82 51
                     "<uses-permission android:name=\"android.permission.FOREGROUND_SERVICE\"/>",
83
-                    "<uses-permission android:name=\"android.permission.FOREGROUND_SERVICE_SPECIAL_USE\" />"
52
+                    "<uses-permission android:name=\"android.permission.FOREGROUND_SERVICE_SPECIAL_USE\"/>"
84 53
                 ],
85
-                "abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ],
54
+                "abiFilters" : [ "armeabi-v7a", "arm64-v8a" ],
86 55
                 "minSdkVersion" : 21,
87 56
                 "autoSdkPermissions" : true,
88
-                "targetSdkVersion" : ""
57
+                "targetSdkVersion" : 33
89 58
             },
90
-            /* ios打包配置 */
91 59
             "ios" : {
92 60
                 "dSYMs" : false,
93
-                "UIBackgroundModes" : "audio,location"
61
+                "UIBackgroundModes" : [ "audio", "location" ]
94 62
             },
95
-            /* SDK配置 */
96 63
             "sdkConfigs" : {
97 64
                 "maps" : {
98 65
                     "amap" : {
@@ -104,7 +71,6 @@
104 71
                 "geolocation" : {
105 72
                     "amap" : {
106 73
                         "__platform__" : [ "android" ],
107
-                        "appkey_ios" : "15e6c1873cf33749320d97869450cdae",
108 74
                         "appkey_android" : "402948be5a1d4d5572c5002b86bd2a23"
109 75
                     },
110 76
                     "system" : {
@@ -173,16 +139,14 @@
173 139
                         "appid_android" : {
174 140
                             "des" : "请填写你当前应用的包名,必需填写,否则可能无法使用。(在菜单中->发行->原生App-云打包中可以查看包名信息)",
175 141
                             "key" : "",
176
-                            "value" : ""
142
+                            "value" : "com.shiyu.app"
177 143
                         }
178 144
                     }
179 145
                 }
180 146
             }
181 147
         }
182 148
     },
183
-    /* 快应用特有相关 */
184 149
     "quickapp" : {},
185
-    /* 小程序特有相关 */
186 150
     "mp-weixin" : {
187 151
         "appid" : "",
188 152
         "setting" : {

+ 2 - 0
mixins/upload.js

@@ -19,6 +19,7 @@ export default {
19 19
         },
20 20
         // H5 平台文件上传
21 21
         handleH5Upload() {
22
+            console.log("H5 平台文件上传")
22 23
             uni.chooseFile({
23 24
                 count: 100, // 最多可以选择100个文件
24 25
                 type: 'all', // 选择所有类型文件
@@ -41,6 +42,7 @@ export default {
41 42
                     }
42 43
 
43 44
                     try {
45
+                        console.log("上传文件成功:1", validFiles)
44 46
                         await Promise.all(validFiles.map(filePath => this.uploadFile(filePath)));
45 47
                         this.handleUploadSuccess();
46 48
                     } catch (error) {

+ 9 - 0
pages.json

@@ -249,6 +249,15 @@
249 249
 				"navigationBarBackgroundColor": "#108cff",
250 250
 				"navigationStyle": "custom"
251 251
 			}
252
+		},
253
+			{
254
+			"path": "pages/pagereceivecenter/pagereceivecenter",
255
+			"style": {
256
+				"navigationBarTitleText": "接单中心",
257
+				"enablePullDownRefresh": false,
258
+				"navigationBarBackgroundColor": "#108cff",
259
+				"navigationStyle": "custom"
260
+			}
252 261
 		}
253 262
 	],
254 263
 	"globalStyle": {

+ 22 - 16
pages/acceptOrderOrder/compounts/orderCard.vue

@@ -1,11 +1,13 @@
1 1
 <template>
2
-    <view class="order-card" :class="{ 'order-card-overTime': order.isDelay }" @click.stop="handleClick(order)">
2
+    <view class="order-card" :class="{ 'order-card-overTime': order && order.isDelay }"
3
+        @click.stop="handleClick(order)">
3 4
         <view class="order-card-header">
4 5
             <view class="order-card-header-left">
5
-                <view class="order-card-header-left-band" style="backgroundColor: #007AFF;" v-show="order.itemBrand">
6
+                <view class="order-card-header-left-band" style="backgroundColor: #007AFF;"
7
+                    v-show="order && order.itemBrand">
6 8
                     {{ order.itemBrand }}
7 9
                 </view>
8
-                <view class="order-card-header-left-band" v-for="value in order.tags" :key="value.id"
10
+                <view class="order-card-header-left-band" v-for="value in (order && order.tags || [])" :key="value.id"
9 11
                     :style="{ backgroundColor: value.color }">
10 12
                     {{ value.name }}
11 13
                 </view>
@@ -15,23 +17,25 @@
15 17
             </view>
16 18
             <view class="order-card-header-right">
17 19
                 <view class="order-card-header-right-price">
18
-                    ¥{{ order.priceRange ? order.priceRange : '暂无价格' }}
20
+                    ¥{{ order && order.priceRange ? order.priceRange : '暂无价格' }}
19 21
                 </view>
20 22
             </view>
21 23
         </view>
22 24
         <view class="order-card-content">
23 25
             <view class="order-card-content-left">
24
-                <image :src="order.image ? order.image : '/static/acceptOrder/orderCardPic.jpg'" mode="scaleToFill" />
26
+                <image :src="(order && order.image) ? order.image : '/static/acceptOrder/orderCardPic.jpg'"
27
+                    mode="scaleToFill" />
25 28
             </view>
26 29
             <view class="order-card-content-right">
27
-                <view>{{ order.item }}</view>
28
-                <view>发单人:{{ order.createNickName }}</view>
29
-                <view>{{ order.sendDate }}</view>
30
+                <view>{{ order && order.item || '暂无项目' }}</view>
31
+                <view>发单人:{{ order && order.createNickName || '未知' }}</view>
32
+                <view>{{ order && order.sendDate || '暂无时间' }}</view>
30 33
             </view>
31 34
         </view>
32 35
 
33 36
         <view class="order-card-bottom">
34
-            <u-row justify="between" v-if="order.status == '1' || order.status == null">
37
+            <u-row justify="between"
38
+                v-if="order && (order.status == '1' || order.status == null || order.status === undefined)">
35 39
                 <u-col span="5.5">
36 40
                     <view @click.stop="handleAcceptOrder(order)">
37 41
                         <u-button type="primary" size="medium">立即接单</u-button>
@@ -44,7 +48,7 @@
44 48
                     </view>
45 49
                 </u-col>
46 50
             </u-row>
47
-            <u-row justify="between" v-if="order.status == '2'">
51
+            <u-row justify="between" v-if="order && order.status == '2'">
48 52
                 <u-col span="5.5">
49 53
                     <view @click.stop="handleWillFollow(order)">
50 54
                         <u-button type="primary" size="medium">待跟进</u-button>
@@ -58,14 +62,14 @@
58 62
                     </view>
59 63
                 </u-col>
60 64
             </u-row>
61
-            <u-row justify="between" v-if="order.status == '3'">
65
+            <u-row justify="between" v-if="order && order.status == '3'">
62 66
                 <u-col span="12">
63 67
                     <view @click.stop="handleShare(order)">
64 68
                         <u-button type="primary" size="medium">一键分享</u-button>
65 69
                     </view>
66 70
                 </u-col>
67 71
             </u-row>
68
-            <u-row justify="between" v-if="order.status == '4'">
72
+            <u-row justify="between" v-if="order && order.status == '4'">
69 73
                 <u-col span="12">
70 74
                     <view @click.stop="handleShare(order)">
71 75
                         <u-button type="primary" size="medium">待跟进</u-button>
@@ -109,8 +113,7 @@ export default {
109 113
         buzyTime: {
110 114
             handler(newVal) {
111 115
                 // console.log('newVal', newVal);
112
-                if (newVal == 0) {
113
-
116
+                if (newVal == 0 && this.order) {
114 117
                     // 移动到最后
115 118
                     this.handleBusy(this.order)
116 119
                 }
@@ -120,8 +123,11 @@ export default {
120 123
     },
121 124
 
122 125
     mounted() {
123
-        this.openTimer()
124
-        console.log('order', this.order);
126
+        // 只有当order对象存在时才启动定时器
127
+        if (this.order) {
128
+            this.openTimer()
129
+            console.log('order', this.order);
130
+        }
125 131
 
126 132
     },
127 133
     beforeDestroy() {

+ 18 - 7
pages/acceptOrderOrder/index.vue

@@ -37,14 +37,25 @@ export default {
37 37
 	methods: {
38 38
 		async getOrderList() {
39 39
 
40
-			const { rows, total } = await uni.$u.api.selectClueOrderFormList({
41
-				pageSize: this.page.pageSize,
42
-				pageNum: this.page.pageNum,
40
+			try {
41
+				const result = await uni.$u.api.selectClueOrderFormList({
42
+					pageSize: this.page.pageSize,
43
+					pageNum: this.page.pageNum,
44
+				});
45
+				// 检查result是否有值,以及是否包含rows和total
46
+				if (result && Array.isArray(result.rows)) {
47
+					console.log('接单列表', result.rows);
48
+					this.ordersList.push(...result.rows);
49
+					// 只有当total存在且为数字时才更新
50
+					if (typeof result.total === 'number') {
51
+						this.page.total = result.total;
52
+					}
53
+				}
54
+			} catch (error) {
55
+				console.error('接单列表接口调用失败:', error);
56
+				// 添加用户友好的错误提示
57
+				uni.$u.toast('获取订单列表失败,请稍后重试');
43 58
 			}
44
-			);
45
-			console.log('接单列表', rows);
46
-			this.ordersList.push(...rows);
47
-			this.page.total = total;
48 59
 		},
49 60
 		scrolltolower() {
50 61
 			if (this.ordersList.length >= this.page.total) {

+ 139 - 138
pages/clueDetail/tabs/callRecord/index.vue

@@ -18,10 +18,10 @@
18 18
 							<uni-icons type="trash" size="20" color="#ff6666"></uni-icons>
19 19
 						</view>
20 20
 					</view>
21
-					<view class="file_name" v-if="data.type === '3'">{{data.fileName}}</view>
21
+					<view class="file_name" v-if="data.type === '3'">{{ data.fileName }}</view>
22 22
 					<view class="call_file">
23 23
 						<view class="audio-container">
24
-							<audio :src="data.fileUrl" controls ></audio>
24
+							<audio :src="data.fileUrl" controls></audio>
25 25
 						</view>
26 26
 					</view>
27 27
 				</view>
@@ -34,171 +34,172 @@
34 34
 	</view>
35 35
 </template>
36 36
 <script>
37
-	export default {
38
-		props: {
39
-			clueId: {
40
-				type: [String, Number],
41
-				required: true
42
-			},
43
-			clueDetail: {
44
-				type: Object,
45
-				default: () => ({})
46
-			}
37
+export default {
38
+	props: {
39
+		clueId: {
40
+			type: [String, Number],
41
+			required: true
47 42
 		},
48
-		data() {
49
-			return {
50
-				dataList: []
51
-			}
43
+		clueDetail: {
44
+			type: Object,
45
+			default: () => ({})
46
+		}
47
+	},
48
+	data() {
49
+		return {
50
+			dataList: []
51
+		}
52
+	},
53
+	methods: {
54
+		titleText(data) {
55
+			return `${data.createTime} 号码(${data.caller}) ${(data.type === 1 ? data.hangupCauseName : '上传录音')}`
52 56
 		},
53
-		methods: {
54
-			titleText(data) {
55
-				return `${data.createTime} 号码(${data.caller}) ${(data.type === 1 ?  data.hangupCauseName: '上传录音')}`
56
-			},
57
-			handleDelete({
58
-				id
59
-			}) {
60
-				uni.showModal({
61
-					title: '提示',
62
-					content: '是否确定删除?',
63
-					confirmColor: '#6cc040',
64
-					success: async (res) => {
65
-						if (res.confirm) {
66
-							try {
67
-								await uni.$u.api.deleteClueFile([id])
68
-								uni.showToast({
69
-									title: '删除成功',
70
-									icon: 'success',
71
-									duration: 2000
72
-								})
73
-								this.getData()
74
-							} catch (error) {
75
-								uni.showToast({
76
-									title: '删除失败',
77
-									icon: 'error',
78
-									duration: 2000
79
-								})
80
-							}
57
+		handleDelete({
58
+			id
59
+		}) {
60
+			uni.showModal({
61
+				title: '提示',
62
+				content: '是否确定删除?',
63
+				confirmColor: '#6cc040',
64
+				success: async (res) => {
65
+					if (res.confirm) {
66
+						try {
67
+							await uni.$u.api.deleteClueFile([id])
68
+							uni.showToast({
69
+								title: '删除成功',
70
+								icon: 'success',
71
+								duration: 2000
72
+							})
73
+							this.getData()
74
+						} catch (error) {
75
+							uni.showToast({
76
+								title: '删除失败',
77
+								icon: 'error',
78
+								duration: 2000
79
+							})
81 80
 						}
82 81
 					}
83
-				})
84
-			},
85
-			async getData() {
86
-				const {
87
-					data
88
-				} = await uni.$u.api.getCallClueFileByClueId({
89
-					clueId: this.clueId
90
-				});
91
-				this.dataList = data;
92
-			},
93
-		},
94
-		mounted() {
95
-			this.getData();
96
-		},
97
-		beforeDestroy(){
98
-			uni.$off('uploadRecordSuccess');  
82
+				}
83
+			})
99 84
 		},
100
-		created() {
101
-			uni.$on('uploadRecordSuccess',()=>{
102
-				this.getData();
85
+		async getData() {
86
+			const {
87
+				data
88
+			} = await uni.$u.api.getCallClueFileByClueId({
89
+				clueId: this.clueId
103 90
 			});
104
-		}
91
+			this.dataList = data;
92
+		},
93
+	},
94
+	mounted() {
95
+		this.getData();
96
+	},
97
+	beforeDestroy() {
98
+		uni.$off('uploadRecordSuccess');
99
+	},
100
+	created() {
101
+		uni.$on('uploadRecordSuccess', () => {
102
+			this.getData();
103
+		});
105 104
 	}
105
+}
106 106
 </script>
107 107
 <style lang="scss" scoped>
108
-	.callRecord_wrap {
109
-		position: relative;
110
-		padding: 20rpx;
111
-		min-height: 400px;
112
-		box-sizing: border-box;
108
+.callRecord_wrap {
109
+	position: relative;
110
+	padding: 20rpx;
111
+	min-height: 400px;
112
+	box-sizing: border-box;
113 113
 
114
-		.loading-mask {
115
-			position: absolute;
116
-			top: 0;
117
-			left: 0;
118
-			right: 0;
119
-			bottom: 0;
120
-			background-color: rgba(255, 255, 255, 0.8);
114
+	.loading-mask {
115
+		position: absolute;
116
+		top: 0;
117
+		left: 0;
118
+		right: 0;
119
+		bottom: 0;
120
+		background-color: rgba(255, 255, 255, 0.8);
121
+		display: flex;
122
+		justify-content: center;
123
+		align-items: center;
124
+		z-index: 999;
125
+	}
126
+
127
+	.timeline-list {
128
+		.timeline-item {
121 129
 			display: flex;
122
-			justify-content: center;
123
-			align-items: center;
124
-			z-index: 999;
125
-		}
130
+			margin-bottom: 30rpx;
126 131
 
127
-		.timeline-list {
128
-			.timeline-item {
132
+			.timeline-icon {
133
+				width: 60rpx;
134
+				height: 60rpx;
135
+				border-radius: 50%;
136
+				background-color: #f1f3f4;
129 137
 				display: flex;
130
-				margin-bottom: 30rpx;
131
-
132
-				.timeline-icon {
133
-					width: 60rpx;
134
-					height: 60rpx;
135
-					border-radius: 50%;
136
-					background-color: #f1f3f4;
137
-					display: flex;
138
-					justify-content: center;
139
-					align-items: center;
140
-					margin-right: 20rpx;
141
-					flex-shrink: 0;
142
-				}
143
-
144
-				.timeline-content {
145
-					width:690rpx;
138
+				justify-content: center;
139
+				align-items: center;
140
+				margin-right: 20rpx;
141
+				flex-shrink: 0;
142
+			}
146 143
 
147
-					.timestamp {
148
-						font-size: 24rpx;
149
-						color: #999;
150
-						margin-bottom: 10rpx;
151
-					}
144
+			.timeline-content {
145
+				width: 690rpx;
152 146
 
153
-					.info_top {
154
-						display: flex;
155
-						justify-content: space-between;
156
-						align-items: center;
157
-						margin-bottom: 20rpx;
147
+				.timestamp {
148
+					font-size: 24rpx;
149
+					color: #999;
150
+					margin-bottom: 10rpx;
151
+				}
158 152
 
159
-						.info_left {
160
-							.name_text {
161
-								font-size: 28rpx;
162
-								font-weight: 500;
163
-							}
164
-						}
153
+				.info_top {
154
+					display: flex;
155
+					justify-content: space-between;
156
+					align-items: center;
157
+					margin-bottom: 20rpx;
165 158
 
166
-						.info_right {
167
-							color: #6cc040;
168
-							font-size: 26rpx;
159
+					.info_left {
160
+						.name_text {
161
+							font-size: 28rpx;
162
+							font-weight: 500;
169 163
 						}
170 164
 					}
171
-					.file_name{
172
-						color: #999;
165
+
166
+					.info_right {
167
+						color: #6cc040;
173 168
 						font-size: 26rpx;
174 169
 					}
170
+				}
175 171
 
176
-					.call_file {
177
-						width: 100%;
178
-						border-radius: 12rpx;
179
-						display: flex;
180
-						align-items: center;
181
-						justify-content: space-between;
182
-						box-sizing: border-box;
172
+				.file_name {
173
+					color: #999;
174
+					font-size: 26rpx;
175
+				}
183 176
 
184
-						.audio-container {
185
-							width: 100%;
186
-						}
177
+				.call_file {
178
+					width: 100%;
179
+					border-radius: 12rpx;
180
+					display: flex;
181
+					align-items: center;
182
+					justify-content: space-between;
183
+					box-sizing: border-box;
184
+
185
+					.audio-container {
186
+						width: 100%;
187 187
 					}
188 188
 				}
189 189
 			}
190 190
 		}
191
+	}
191 192
 
192
-		.empty_wrap {
193
-			text-align: center;
194
-			padding: 100rpx 0;
193
+	.empty_wrap {
194
+		text-align: center;
195
+		padding: 100rpx 0;
195 196
 
196
-			.empty-text {
197
-				display: block;
198
-				margin-top: 30rpx;
199
-				color: #999;
200
-				font-size: 28rpx;
201
-			}
197
+		.empty-text {
198
+			display: block;
199
+			margin-top: 30rpx;
200
+			color: #999;
201
+			font-size: 28rpx;
202 202
 		}
203 203
 	}
204
+}
204 205
 </style>

+ 159 - 158
pages/order/components/orderCenter/orderCenter.vue

@@ -11,14 +11,14 @@
11 11
 				<u-icon name="arrow-down-fill" color="#aaa" size="10"></u-icon>
12 12
 			</view>
13 13
 		</view>
14
-		
14
+
15 15
 		<view class="send_status_wrap">
16 16
 			<scroll-view scroll-x="true">
17 17
 				<view class="clue_state_list">
18
-					<view @click="handleSendStatusClick(item)" v-for="(item, index) in clueSendStatusCountList " :key="index"
19
-						class="clue_state_item" :class="{ active : queryParams.status === item.status }">
20
-						<text>{{item.statusName}}</text>
21
-						<text>({{item.count}})</text>
18
+					<view @click="handleSendStatusClick(item)" v-for="(item, index) in clueSendStatusCountList"
19
+						:key="index" class="clue_state_item" :class="{ active: queryParams.status === item.status }">
20
+						<text>{{ item.statusName }}</text>
21
+						<text>({{ item.count }})</text>
22 22
 					</view>
23 23
 				</view>
24 24
 			</scroll-view>
@@ -40,181 +40,182 @@
40 40
 </template>
41 41
 
42 42
 <script>
43
-	import pullUpRefresh from "@/utils/pullUpRefresh";
44
-	import filterQuery from "./filterQuery.vue";
45
-	import orderItem from "./orderItem.vue";
46
-	export default {
47
-		mixins: [pullUpRefresh],
48
-		props: {
49
-			type: {
50
-				type: String,
51
-				default: '2'
43
+import pullUpRefresh from "@/utils/pullUpRefresh";
44
+import filterQuery from "./filterQuery.vue";
45
+import orderItem from "./orderItem.vue";
46
+export default {
47
+	mixins: [pullUpRefresh],
48
+	props: {
49
+		type: {
50
+			type: String,
51
+			default: '2'
52
+		},
53
+		dicts: {
54
+			type: Object,
55
+			required: true
56
+		}
57
+	},
58
+	components: {
59
+		filterQuery,
60
+		orderItem
61
+	},
62
+	data() {
63
+		return {
64
+			// 可以添加特定于接单中心的参数
65
+			queryParams: {
66
+				sendDateStart: '',
67
+				sendDateEnd: '',
68
+				type: '2',
69
+				item: undefined,
70
+				phone: undefined,
71
+				deptId: undefined,
72
+				state: undefined,
73
+				status: undefined,
74
+				allTagList: [],
75
+				identification: undefined,
76
+				createBy: undefined,
77
+				pageNum: 1,
78
+				pageSize: 10,
52 79
 			},
53
-			dicts: {
54
-				type: Object,
55
-				required: true
56
-			}
80
+
81
+			clueSendStatusCountList: [],
82
+
83
+			mapHeight: "0px"
84
+		}
85
+	},
86
+	methods: {
87
+		getOtherData() {
88
+			this.statisticsSendStatus();
57 89
 		},
58
-		components: {
59
-			filterQuery,
60
-			orderItem
90
+		async statisticsSendStatus() {
91
+			const {
92
+				data
93
+			} = await uni.$u.api.statisticsSendStatus(this.queryParams);
94
+			this.clueSendStatusCountList = data;
61 95
 		},
62
-		data() {
63
-			return {
64
-				// 可以添加特定于接单中心的参数
65
-				queryParams: {
66
-					sendDateStart: '',
67
-					sendDateEnd: '',
68
-					type: '2',
69
-					item: undefined,
70
-					phone: undefined,
71
-					deptId: undefined,
72
-					state: undefined,
73
-					status: undefined,
74
-					allTagList: [],
75
-					identification: undefined,
76
-					createBy: undefined,
77
-					pageNum: 1,
78
-					pageSize: 10,
79
-				},
80
-				
81
-				clueSendStatusCountList : [],
82
-
83
-				mapHeight: "0px"
84
-			}
96
+		handleSendStatusClick(item) {
97
+			this.queryParams.status = item.status;
98
+			this.resetData();
85 99
 		},
86
-		methods: {
87
-			getOtherData() {
88
-				this.statisticsSendStatus();
89
-			},
90
-			async statisticsSendStatus() {
91
-				const {
92
-					data
93
-				} = await uni.$u.api.statisticsSendStatus(this.queryParams);
94
-				this.clueSendStatusCountList = data;
95
-			},
96
-			handleSendStatusClick(item) {
97
-				this.queryParams.status = item.status;
98
-				this.resetData();
99
-			},
100
-			handleKeyword() {
101
-				this.resetData();
102
-			},
103
-			handleKeywordClear() {
104
-				// 组件有bug 清空后的值还是存在
105
-				this.queryParams.phone = "";
106
-				this.resetData();
107
-			},
108
-			handleshowFilter() {
109
-				this.$refs.filter.show();
110
-			},
111
-			async getList() {
112
-				const {
113
-					pageNum,
114
-					pageSize,
115
-				} = this.queryParams;
116
-				this.queryParams.type = this.type;
117
-				// 调用接单中心的接口
118
-				const {
119
-					rows,
120
-					total
121
-				} = await uni.$u.api.selectClueOrderFormList({
122
-						pageSize,
123
-						pageNum
124
-					},
125
-					this.queryParams
126
-				);
127
-				return rows;
128
-			},
129
-			handleOnReachBottom() {
130
-				this.handleReachBottom();
131
-			}
100
+		handleKeyword() {
101
+			this.resetData();
132 102
 		},
133
-		mounted() {
103
+		handleKeywordClear() {
104
+			// 组件有bug 清空后的值还是存在
105
+			this.queryParams.phone = "";
134 106
 			this.resetData();
135
-			// 根据路由名称设置类型
107
+		},
108
+		handleshowFilter() {
109
+			this.$refs.filter.show();
110
+		},
111
+		async getList() {
112
+			const {
113
+				pageNum,
114
+				pageSize,
115
+			} = this.queryParams;
136 116
 			this.queryParams.type = this.type;
137
-			uni.getSystemInfo({
138
-				success: (e) => {
139
-					const {
140
-						windowTop,
141
-						windowBottom,
142
-						windowHeight
143
-					} = e;
144
-					this.mapHeight = (windowHeight - 70) + 'px';
145
-				}
146
-			});
117
+			// 调用接单中心的接口
118
+			const {
119
+				rows,
120
+				total
121
+			} = await uni.$u.api.selectClueOrderFormList({
122
+				pageSize,
123
+				pageNum
124
+			},
125
+				this.queryParams
126
+			);
127
+			return rows;
147 128
 		},
148
-	}
129
+		handleOnReachBottom() {
130
+			this.handleReachBottom();
131
+		}
132
+	},
133
+	mounted() {
134
+		this.resetData();
135
+		// 根据路由名称设置类型
136
+		this.queryParams.type = this.type;
137
+		uni.getSystemInfo({
138
+			success: (e) => {
139
+				const {
140
+					windowTop,
141
+					windowBottom,
142
+					windowHeight
143
+				} = e;
144
+				this.mapHeight = (windowHeight - 70) + 'px';
145
+			}
146
+		});
147
+	},
148
+}
149 149
 </script>
150 150
 
151 151
 <style lang="scss" scoped>
152
-	.send_status_wrap {
153
-		width: 690rpx;
154
-		padding: 0 30rpx;
155
-		margin-top: 20rpx;
152
+.send_status_wrap {
153
+	width: 690rpx;
154
+	padding: 0 30rpx;
155
+	margin-top: 20rpx;
156
+	display: flex;
157
+
158
+	.clue_state_list {
156 159
 		display: flex;
157
-	
158
-		.clue_state_list {
159
-			display: flex;
160
-	
161
-			.clue_state_item {
162
-				font-size: 30rpx;
163
-				display: inline-flex;
164
-				/* 关键改动:改为行内弹性盒子 */
165
-				align-items: center;
166
-				/* 垂直居中 */
167
-				background: #fff;
168
-				margin-right: 30rpx;
169
-				padding: 8rpx 16rpx;
170
-				/* 增加内边距 */
171
-				white-space: nowrap;
172
-				/* 关键:禁止文本换行 */
173
-				border-radius: 6rpx;
174
-	
175
-				&.active {
176
-					color: #fff;
177
-					background: #4c8afe;
178
-				}
160
+
161
+		.clue_state_item {
162
+			font-size: 30rpx;
163
+			display: inline-flex;
164
+			/* 关键改动:改为行内弹性盒子 */
165
+			align-items: center;
166
+			/* 垂直居中 */
167
+			background: #fff;
168
+			margin-right: 30rpx;
169
+			padding: 8rpx 16rpx;
170
+			/* 增加内边距 */
171
+			white-space: nowrap;
172
+			/* 关键:禁止文本换行 */
173
+			border-radius: 6rpx;
174
+
175
+			&.active {
176
+				color: #fff;
177
+				background: #4c8afe;
179 178
 			}
180 179
 		}
181 180
 	}
182
-	.order_center_wrap {
183
-		box-sizing: border-box;
184
-		min-height: 100vh;
181
+}
185 182
 
186
-		.queryParams_wrap {
187
-			display: flex;
188
-			background: #fff;
189
-			padding: 14px 0;
183
+.order_center_wrap {
184
+	box-sizing: border-box;
185
+	min-height: 100vh;
190 186
 
187
+	.queryParams_wrap {
188
+		display: flex;
189
+		background: #fff;
190
+		padding: 14px 0;
191 191
 
192
-			.query,
193
-			.search {
194
-				display: flex;
195
-				align-items: center;
196
-				justify-content: center;
197
-				font-size: 16px;
198
-				font-weight: 700;
199
-				color: #202020;
200
-			}
201 192
 
202
-			.query {
203
-				flex: 1;
204
-			}
193
+		.query,
194
+		.search {
195
+			display: flex;
196
+			align-items: center;
197
+			justify-content: center;
198
+			font-size: 16px;
199
+			font-weight: 700;
200
+			color: #202020;
201
+		}
205 202
 
206
-			.search {
207
-				flex: 2;
208
-				padding-left: 20px;
209
-			}
203
+		.query {
204
+			flex: 1;
210 205
 		}
211
-	}
212 206
 
213
-	.order_item_wrap {
214
-		padding: 10px 20px;
207
+		.search {
208
+			flex: 2;
209
+			padding-left: 20px;
210
+		}
215 211
 	}
212
+}
216 213
 
217
-	.empty_wrap {
218
-		margin-top: 100px;
219
-	}
214
+.order_item_wrap {
215
+	padding: 10px 20px;
216
+}
217
+
218
+.empty_wrap {
219
+	margin-top: 100px;
220
+}
220 221
 </style>

+ 84 - 84
pages/order/index.vue

@@ -11,104 +11,104 @@
11 11
 				<orderCenter ref="myOrder" type="2" :dicts="dicts"></orderCenter>
12 12
 			</template>
13 13
 			<template #myCommission>
14
-				<myCommission ref="myCommission" type="2" :showStats="true" ></myCommission>
14
+				<myCommission ref="myCommission" type="2" :showStats="true"></myCommission>
15 15
 			</template>
16 16
 		</yui-tabs>
17 17
 	</view>
18 18
 </template>
19 19
 
20 20
 <script>
21
-	import orderCenter from "./components/orderCenter/orderCenter.vue";
22
-	import myCommission from "./components/commission/myCommission.vue";
21
+import orderCenter from "./components/orderCenter/orderCenter.vue";
22
+import myCommission from "./components/commission/myCommission.vue";
23 23
 
24
-	export default {
25
-		components: {
26
-			orderCenter,
27
-			myCommission
24
+export default {
25
+	components: {
26
+		orderCenter,
27
+		myCommission
28
+	},
29
+	onPullDownRefresh() {
30
+		uni.stopPullDownRefresh();
31
+		this.$refs[this.activeTel].resetData();
32
+	},
33
+	onReachBottom() {
34
+		this.$refs[this.activeTel].handleOnReachBottom();
35
+	},
36
+	computed: {
37
+		activeTel() {
38
+			return this.tabs.find(v => v.activeIndex === this.activeIndex).slot;
28 39
 		},
29
-		onPullDownRefresh() {
30
-			uni.stopPullDownRefresh();
31
-			this.$refs[this.activeTel].resetData();
32
-		},
33
-		onReachBottom() {
34
-			this.$refs[this.activeTel].handleOnReachBottom();
35
-		},
36
-		computed: {
37
-			activeTel() {
38
-				return this.tabs.find(v => v.activeIndex === this.activeIndex).slot;
39
-			},
40
-		},
41
-		data() {
42
-			return {
40
+	},
41
+	data() {
42
+		return {
43
+			activeIndex: 0,
44
+			offsetTop: 0,
45
+			tabs: [{
46
+				label: '接单中心',
47
+				slot: 'orderCenter',
43 48
 				activeIndex: 0,
44
-				offsetTop: 0,
45
-				tabs: [{
46
-						label: '接单中心',
47
-						slot: 'orderCenter',
48
-						activeIndex: 0,
49
-					}, {
50
-						label: '我的接发单',
51
-						slot: 'myOrder',
52
-						activeIndex: 1,
53
-					},
54
-					{
55
-						label: '我的分成',
56
-						slot: 'myCommission',
57
-						activeIndex: 2,
58
-					}
59
-				],
60
-				dicts : {
61
-					crmFormStatusDict : [],
62
-					crmFormCategoryDict : [],
63
-					crmFormStateDict : [],
64
-					crmFormTacticDict : [],
65
-				}
49
+			}, {
50
+				label: '我的接发单',
51
+				slot: 'myOrder',
52
+				activeIndex: 1,
53
+			},
54
+			{
55
+				label: '我的分成',
56
+				slot: 'myCommission',
57
+				activeIndex: 2,
66 58
 			}
67
-		},
68
-		mounted() {
69
-			// 页面初始化后的逻辑
70
-			uni.getSystemInfo({
71
-				success: (e) => {
72
-					let offsetTop = 0
73
-					// #ifdef H5
74
-					offsetTop = 43
75
-					// #endif
76
-					this.offsetTop = offsetTop;
77
-				}
78
-			});
79
-			this.$getDicts('crm_form_status').then(res => {
80
-				this.dicts.crmFormStatusDict = res;
81
-			});
82
-			this.$getDicts('crm_form_category').then(res => {
83
-				this.dicts.crmFormCategoryDict = res;
84
-			});
85
-			this.$getDicts('crm_form_state').then(res => {
86
-				this.dicts.crmFormStateDict = res;
87
-			});
88
-			this.$getDicts('crm_form_tactic').then(res => {
89
-				this.dicts.crmFormTacticDict = res;
90
-			});
91
-		},
92
-		methods: {
93
-			// tab切换事件处理
94
-			handleTabChange(index) {
95
-				this.activeIndex = index;
59
+			],
60
+			dicts: {
61
+				crmFormStatusDict: [],
62
+				crmFormCategoryDict: [],
63
+				crmFormStateDict: [],
64
+				crmFormTacticDict: [],
96 65
 			}
97
-		},
98
-		// 页面滚动触发事件
99
-		onPageScroll(e) {
100
-			//页面滚动事件
101
-			uni.$emit('onPageScroll', e)
102
-		},
103
-	}
66
+		}
67
+	},
68
+	mounted() {
69
+		// 页面初始化后的逻辑
70
+		uni.getSystemInfo({
71
+			success: (e) => {
72
+				let offsetTop = 0
73
+				// #ifdef H5
74
+				offsetTop = 43
75
+				// #endif
76
+				this.offsetTop = offsetTop;
77
+			}
78
+		});
79
+		this.$getDicts('crm_form_status').then(res => {
80
+			this.dicts.crmFormStatusDict = res;
81
+		});
82
+		this.$getDicts('crm_form_category').then(res => {
83
+			this.dicts.crmFormCategoryDict = res;
84
+		});
85
+		this.$getDicts('crm_form_state').then(res => {
86
+			this.dicts.crmFormStateDict = res;
87
+		});
88
+		this.$getDicts('crm_form_tactic').then(res => {
89
+			this.dicts.crmFormTacticDict = res;
90
+		});
91
+	},
92
+	methods: {
93
+		// tab切换事件处理
94
+		handleTabChange(index) {
95
+			this.activeIndex = index;
96
+		}
97
+	},
98
+	// 页面滚动触发事件
99
+	onPageScroll(e) {
100
+		//页面滚动事件
101
+		uni.$emit('onPageScroll', e)
102
+	},
103
+}
104 104
 </script>
105 105
 
106 106
 <style lang="scss" scoped>
107
-	::v-deep .yui-tabs__content {
108
-		background-color: transparent;
107
+::v-deep .yui-tabs__content {
108
+	background-color: transparent;
109 109
 
110
-		.yui-tabs__track {
111
-			background-color: transparent;
112
-		}
110
+	.yui-tabs__track {
111
+		background-color: transparent;
113 112
 	}
113
+}
114 114
 </style>

+ 44 - 43
pages/orderDetail/index.vue

@@ -3,7 +3,7 @@
3 3
 		<u-navbar placeholder :autoBack="true" v-hideNav>
4 4
 			<template slot="center">
5 5
 				<view class="navbar_center_wrap">
6
-					<text class="name">{{item}}</text>
6
+					<text class="name">{{ item }}</text>
7 7
 				</view>
8 8
 			</template>
9 9
 		</u-navbar>
@@ -12,52 +12,53 @@
12 12
 </template>
13 13
 
14 14
 <script>
15
-	import detail from "./page/detail.vue";
16
-	import qs from 'qs';
17
-	export default {
18
-		components: {
19
-			detail
20
-		},
21
-		onPullDownRefresh() {
22
-			uni.stopPullDownRefresh();
23
-			// 刷新
24
-			uni.redirectTo({
25
-				url : `/pages/orderDetail/index?` + qs.stringify(this.params),
26
-			})
27
-		},
28
-		onLoad(option) {
29
-			const {	item , orderId , type , clueId } = option;
30
-			this.item = item;
31
-			this.orderId = orderId;
32
-			this.params = option;
33
-			this.clueId = clueId;
34
-			uni.setNavigationBarTitle({
35
-				title: item
36
-			});
37
-		},
38
-		data() {
39
-			return {
40
-				item: "", 
41
-				orderId: "",
42
-				clueId: "",
43
-				params : {},
44
-			}
45
-		},
46
-		mounted(){
15
+import detail from "./page/detail.vue";
16
+import qs from 'qs';
17
+export default {
18
+	components: {
19
+		detail
20
+	},
21
+	onPullDownRefresh() {
22
+		uni.stopPullDownRefresh();
23
+		// 刷新
24
+		uni.redirectTo({
25
+			url: `/pages/orderDetail/index?` + qs.stringify(this.params),
26
+		})
27
+	},
28
+	onLoad(option) {
29
+		const { item, orderId, type, clueId } = option;
30
+		this.item = item;
31
+		this.orderId = orderId;
32
+		this.params = option;
33
+		this.clueId = clueId;
34
+		uni.setNavigationBarTitle({
35
+			title: item
36
+		});
37
+	},
38
+	data() {
39
+		return {
40
+			item: "",
41
+			orderId: "",
42
+			clueId: "",
43
+			params: {},
47 44
 		}
45
+	},
46
+	mounted() {
48 47
 	}
48
+}
49 49
 </script>
50 50
 
51 51
 <style lang="scss" scoped>
52
-	.navbar_center_wrap{
53
-		text-align: center;
54
-		width: 200rpx;
55
-		display: flex;
56
-		flex-direction: column;
57
-		align-items: center;
58
-		.pinyin{
59
-			font-size: 22rpx;
60
-			color: #b3b3c6;
61
-		}
52
+.navbar_center_wrap {
53
+	text-align: center;
54
+	width: 200rpx;
55
+	display: flex;
56
+	flex-direction: column;
57
+	align-items: center;
58
+
59
+	.pinyin {
60
+		font-size: 22rpx;
61
+		color: #b3b3c6;
62 62
 	}
63
+}
63 64
 </style>

+ 437 - 437
pages/orderDetail/page/detail.vue

@@ -145,497 +145,497 @@
145 145
 </template>
146 146
 
147 147
 <script>
148
-	import {
149
-		cloneDeep
150
-	} from "lodash";
151
-	import {
152
-		selectDictLabel
153
-	} from "@/utils/util";
154
-	import uploadFile from "../tabs/uploadFile/index.vue";
155
-	import clueFollow from "../tabs/followRecord/index.vue";
156
-	import receiptFormList from "../tabs/receiptFormList/receiptFormList.vue";
157
-	import commissionFormList from "../tabs/commissionFormList/commissionFormList.vue";
158
-	import sendInfo from "../tabs/sendInfo/index.vue";
159
-	export default {
160
-		components: {
161
-			uploadFile,
162
-			clueFollow,
163
-			receiptFormList,
164
-			commissionFormList,
165
-			sendInfo
148
+import {
149
+	cloneDeep
150
+} from "lodash";
151
+import {
152
+	selectDictLabel
153
+} from "@/utils/util";
154
+import uploadFile from "../tabs/uploadFile/index.vue";
155
+import clueFollow from "../tabs/followRecord/index.vue";
156
+import receiptFormList from "../tabs/receiptFormList/receiptFormList.vue";
157
+import commissionFormList from "../tabs/commissionFormList/commissionFormList.vue";
158
+import sendInfo from "../tabs/sendInfo/index.vue";
159
+export default {
160
+	components: {
161
+		uploadFile,
162
+		clueFollow,
163
+		receiptFormList,
164
+		commissionFormList,
165
+		sendInfo
166
+	},
167
+	props: {
168
+		orderId: {
169
+			type: [String, Number],
170
+			required: true,
166 171
 		},
167
-		props: {
168
-			orderId: {
169
-				type: [String, Number],
170
-				required: true,
171
-			},
172
-			clueId: {
173
-				type: [String, Number],
174
-				required: true,
175
-			},
176
-			params: {
177
-				type: Object,
178
-				required: true,
179
-			},
172
+		clueId: {
173
+			type: [String, Number],
174
+			required: true,
180 175
 		},
181
-		data() {
182
-			return {
183
-				showModal: false,
184
-				showStateSelect: false,
185
-				receiptDetail: {},
186
-				checkTags: [],
187
-				clueTagGroupVoList: [],
188
-				crmFormCategoryDict: [],
189
-				crmFormTacticDict: [],
190
-				crmFormStateDict: [],
191
-				crmHandelStatusDict: [],
192
-				tabs: [{
193
-						label: "发单信息",
194
-						slot: "sendInfo",
195
-					},
196
-					{
197
-						label: "聊天附件",
198
-						slot: "chatFile",
199
-					},
200
-					{
201
-						label: "报价附件",
202
-						slot: "quoteFile",
203
-					},
204
-					{
205
-						label: "高清图附件",
206
-						slot: "hdImageFile",
207
-					},
208
-					{
209
-						label: "其他附件",
210
-						slot: "otherFile",
211
-					},
212
-					{
213
-						label: "前端附件",
214
-						slot: "frontendFile",
215
-					},
216
-					{
217
-						label: "前端跟进",
218
-						slot: "frontendFollow",
219
-					},
220
-					{
221
-						label: "跟进记录",
222
-						slot: "followRecord",
223
-					},
224
-					{
225
-						label: "收单信息",
226
-						slot: "receiptInfo",
227
-					},
228
-					{
229
-						label: "收单分成",
230
-						slot: "commissionInfo",
231
-					},
232
-				],
233
-				activeIndex: 0,
234
-			};
176
+		params: {
177
+			type: Object,
178
+			required: true,
235 179
 		},
236
-		methods: {
237
-			async hanldeTagClose(tag) {
238
-				const {
239
-					id,
240
-					tags
241
-				} = this.receiptDetail;
242
-				const copyTags = cloneDeep(tags);
243
-				if (id == null) {
244
-					uni.$u.toast("修改异常");
245
-					return;
246
-				}
247
-				const index = copyTags.findIndex((v) => v.id === tag.id);
248
-				if (index !== -1) {
249
-					copyTags.splice(index, 1);
250
-					const allTags = copyTags.map((v) => v.id).join(",");
251
-					await uni.$u.api.updateTags({
252
-						id: id,
253
-						allTags,
254
-					});
255
-					this.receiptDetail.tags = copyTags;
256
-					this.checkTags = this.receiptDetail.tags.map((v) => v.id);
257
-				}
258
-			},
259
-			async handleClueTagConfirm() {
260
-				const allTags = this.checkTags.join(",");
261
-				await uni.$u.api.updateTags({
262
-					id: this.receiptDetail.id,
263
-					allTags,
264
-				});
265
-				this.getDetail();
266
-			},
267
-			handleAddClueTag() {
268
-				this.$refs.clueTag.showModal();
180
+	},
181
+	data() {
182
+		return {
183
+			showModal: false,
184
+			showStateSelect: false,
185
+			receiptDetail: {},
186
+			checkTags: [],
187
+			clueTagGroupVoList: [],
188
+			crmFormCategoryDict: [],
189
+			crmFormTacticDict: [],
190
+			crmFormStateDict: [],
191
+			crmHandelStatusDict: [],
192
+			tabs: [{
193
+				label: "发单信息",
194
+				slot: "sendInfo",
269 195
 			},
270
-			async handleStateConfirm(e) {
271
-				const state = e.dictValue;
272
-				await uni.$u.api.updateOrderState({
273
-					id: this.receiptDetail.id,
274
-					state,
275
-				});
276
-				uni.$u.toast("操作成功");
196
+			{
197
+				label: "聊天附件",
198
+				slot: "chatFile",
277 199
 			},
278
-			defaultText(text) {
279
-				return text ? text : "-";
200
+			{
201
+				label: "报价附件",
202
+				slot: "quoteFile",
280 203
 			},
281
-			crmFormCategoryFormat(v) {
282
-				return v ? selectDictLabel(this.crmFormCategoryDict, v) : "-";
204
+			{
205
+				label: "高清图附件",
206
+				slot: "hdImageFile",
283 207
 			},
284
-			crmFormTacticFormat(v) {
285
-				return v ? selectDictLabel(this.crmFormTacticDict, v) : "-";
208
+			{
209
+				label: "其他附件",
210
+				slot: "otherFile",
286 211
 			},
287
-			crmFollowStatusFormat(v) {
288
-				return selectDictLabel(this.crmHandelStatusDict, v);
212
+			{
213
+				label: "前端附件",
214
+				slot: "frontendFile",
289 215
 			},
290
-			selectDictLabel,
291
-			handleCopy(item) {
292
-				uni.setClipboardData({
293
-					data: item.phone,
294
-					success: function() {
295
-						uni.$u.toast("复制成功");
296
-					},
297
-				});
216
+			{
217
+				label: "前端跟进",
218
+				slot: "frontendFollow",
298 219
 			},
299
-			// 添加联系人
300
-			handleCallPhone() {
301
-				uni.makePhoneCall({
302
-					phoneNumber: this.receiptDetail.phone,
303
-					success: () => {
304
-						this.$store.commit("call/SET_FORM", {
305
-							clueId: this.receiptDetail.clueId,
306
-							type: "3",
307
-							callee: this.receiptDetail.phone,
308
-						});
309
-					},
310
-				});
311
-			},
312
-			// 添加跟进记录
313
-			handleAddFollow() {
314
-				uni.navigateTo({
315
-					url: `/pages/addFollow/index?orderId=${this.orderId}`,
316
-				});
220
+			{
221
+				label: "跟进记录",
222
+				slot: "followRecord",
317 223
 			},
318
-			// 跳转到收单表单页面
319
-			handleAddReceiptForm() {
320
-				uni.navigateTo({
321
-					url: `/pages/receiptForm/index?orderId=${this.orderId}&clueId=${this.clueId}`,
322
-				});
224
+			{
225
+				label: "收单信息",
226
+				slot: "receiptInfo",
323 227
 			},
324
-			// 跳转到新增分成页面
325
-			handleAddCommission() {
326
-				if(this.receiptDetail.status != "3"){
327
-					uni.$u.toast("未收单不可添加分成");
328
-					return;
329
-				}
330
-				uni.navigateTo({
331
-					url: `/pages/commissionForm/index?sendFormId=${this.orderId}&clueId=${this.clueId}`,
332
-				});
228
+			{
229
+				label: "收单分成",
230
+				slot: "commissionInfo",
333 231
 			},
334
-			handleUploadRecord() {
335
-				uni.navigateTo({
336
-					url: `/pages/uploadRecord/index?clueId=${this.orderId}`,
232
+			],
233
+			activeIndex: 0,
234
+		};
235
+	},
236
+	methods: {
237
+		async hanldeTagClose(tag) {
238
+			const {
239
+				id,
240
+				tags
241
+			} = this.receiptDetail;
242
+			const copyTags = cloneDeep(tags);
243
+			if (id == null) {
244
+				uni.$u.toast("修改异常");
245
+				return;
246
+			}
247
+			const index = copyTags.findIndex((v) => v.id === tag.id);
248
+			if (index !== -1) {
249
+				copyTags.splice(index, 1);
250
+				const allTags = copyTags.map((v) => v.id).join(",");
251
+				await uni.$u.api.updateTags({
252
+					id: id,
253
+					allTags,
337 254
 				});
338
-			},
339
-			// 接单操作
340
-			async handleOrderForm() {
341
-				if (this.receiptDetail.status === "2") {
342
-					uni.$u.toast("当前订单已经被接单");
343
-					return;
344
-				}
345
-				uni.showModal({
346
-					title: "提示",
347
-					content: "确定要接单吗?",
348
-					success: async (res) => {
349
-						if (res.confirm) {
350
-							try {
351
-								await uni.$u.api.oderForm({
352
-									status: "2",
353
-									id: this.receiptDetail.id,
354
-								});
355
-								uni.$u.toast("接单成功");
356
-								this.getDetail(); // 刷新详情
357
-							} catch (error) {
358
-								uni.$u.toast("接单失败");
359
-							}
255
+				this.receiptDetail.tags = copyTags;
256
+				this.checkTags = this.receiptDetail.tags.map((v) => v.id);
257
+			}
258
+		},
259
+		async handleClueTagConfirm() {
260
+			const allTags = this.checkTags.join(",");
261
+			await uni.$u.api.updateTags({
262
+				id: this.receiptDetail.id,
263
+				allTags,
264
+			});
265
+			this.getDetail();
266
+		},
267
+		handleAddClueTag() {
268
+			this.$refs.clueTag.showModal();
269
+		},
270
+		async handleStateConfirm(e) {
271
+			const state = e.dictValue;
272
+			await uni.$u.api.updateOrderState({
273
+				id: this.receiptDetail.id,
274
+				state,
275
+			});
276
+			uni.$u.toast("操作成功");
277
+		},
278
+		defaultText(text) {
279
+			return text ? text : "-";
280
+		},
281
+		crmFormCategoryFormat(v) {
282
+			return v ? selectDictLabel(this.crmFormCategoryDict, v) : "-";
283
+		},
284
+		crmFormTacticFormat(v) {
285
+			return v ? selectDictLabel(this.crmFormTacticDict, v) : "-";
286
+		},
287
+		crmFollowStatusFormat(v) {
288
+			return selectDictLabel(this.crmHandelStatusDict, v);
289
+		},
290
+		selectDictLabel,
291
+		handleCopy(item) {
292
+			uni.setClipboardData({
293
+				data: item.phone,
294
+				success: function () {
295
+					uni.$u.toast("复制成功");
296
+				},
297
+			});
298
+		},
299
+		// 添加联系人
300
+		handleCallPhone() {
301
+			uni.makePhoneCall({
302
+				phoneNumber: this.receiptDetail.phone,
303
+				success: () => {
304
+					this.$store.commit("call/SET_FORM", {
305
+						clueId: this.receiptDetail.clueId,
306
+						type: "3",
307
+						callee: this.receiptDetail.phone,
308
+					});
309
+				},
310
+			});
311
+		},
312
+		// 添加跟进记录
313
+		handleAddFollow() {
314
+			uni.navigateTo({
315
+				url: `/pages/addFollow/index?orderId=${this.orderId}`,
316
+			});
317
+		},
318
+		// 跳转到收单表单页面
319
+		handleAddReceiptForm() {
320
+			uni.navigateTo({
321
+				url: `/pages/receiptForm/index?orderId=${this.orderId}&clueId=${this.clueId}`,
322
+			});
323
+		},
324
+		// 跳转到新增分成页面
325
+		handleAddCommission() {
326
+			if (this.receiptDetail.status != "3") {
327
+				uni.$u.toast("未收单不可添加分成");
328
+				return;
329
+			}
330
+			uni.navigateTo({
331
+				url: `/pages/commissionForm/index?sendFormId=${this.orderId}&clueId=${this.clueId}`,
332
+			});
333
+		},
334
+		handleUploadRecord() {
335
+			uni.navigateTo({
336
+				url: `/pages/uploadRecord/index?clueId=${this.orderId}`,
337
+			});
338
+		},
339
+		// 接单操作
340
+		async handleOrderForm() {
341
+			if (this.receiptDetail.status === "2") {
342
+				uni.$u.toast("当前订单已经被接单");
343
+				return;
344
+			}
345
+			uni.showModal({
346
+				title: "提示",
347
+				content: "确定要接单吗?",
348
+				success: async (res) => {
349
+					if (res.confirm) {
350
+						try {
351
+							await uni.$u.api.oderForm({
352
+								status: "2",
353
+								id: this.receiptDetail.id,
354
+							});
355
+							uni.$u.toast("接单成功");
356
+							this.getDetail(); // 刷新详情
357
+						} catch (error) {
358
+							uni.$u.toast("接单失败");
360 359
 						}
361
-					},
362
-				});
363
-			},
364
-			// 收单操作
365
-			async handleReceiptForm() {
366
-				if (
367
-					this.receiptDetail.status === "3" ||
368
-					this.receiptDetail.status === "4"
369
-				) {
370
-					uni.$u.toast("当前订单已经被收单或未收");
371
-					return;
372
-				}
373
-				uni.showModal({
374
-					title: "提示",
375
-					content: "确定要收单吗?",
376
-					success: async (res) => {
377
-						if (res.confirm) {
378
-							try {
379
-								await uni.$u.api.oderForm({
380
-									status: "3",
381
-									id: this.receiptDetail.id,
382
-								});
383
-								uni.$u.toast("收单成功");
384
-								this.getDetail(); // 刷新详情
385
-							} catch (error) {
386
-								uni.$u.toast("收单失败");
387
-							}
360
+					}
361
+				},
362
+			});
363
+		},
364
+		// 收单操作
365
+		async handleReceiptForm() {
366
+			if (
367
+				this.receiptDetail.status === "3" ||
368
+				this.receiptDetail.status === "4"
369
+			) {
370
+				uni.$u.toast("当前订单已经被收单或未收");
371
+				return;
372
+			}
373
+			uni.showModal({
374
+				title: "提示",
375
+				content: "确定要收单吗?",
376
+				success: async (res) => {
377
+					if (res.confirm) {
378
+						try {
379
+							await uni.$u.api.oderForm({
380
+								status: "3",
381
+								id: this.receiptDetail.id,
382
+							});
383
+							uni.$u.toast("收单成功");
384
+							this.getDetail(); // 刷新详情
385
+						} catch (error) {
386
+							uni.$u.toast("收单失败");
388 387
 						}
389
-					},
390
-				});
391
-			},
392
-			// 未收操作
393
-			async handleDenialForm() {
394
-				if (
395
-					this.receiptDetail.status === "3" ||
396
-					this.receiptDetail.status === "4"
397
-				) {
398
-					uni.$u.toast("当前订单已经被收单或未收");
399
-					return;
400
-				}
401
-				uni.showModal({
402
-					title: "提示",
403
-					content: "确定要标记为未收吗?",
404
-					success: async (res) => {
405
-						if (res.confirm) {
406
-							try {
407
-								await uni.$u.api.oderForm({
408
-									status: "4",
409
-									id: this.receiptDetail.id,
410
-								});
411
-								uni.$u.toast("标记未收成功");
412
-								this.getDetail(); // 刷新详情
413
-							} catch (error) {
414
-								uni.$u.toast("操作失败");
415
-							}
388
+					}
389
+				},
390
+			});
391
+		},
392
+		// 未收操作
393
+		async handleDenialForm() {
394
+			if (
395
+				this.receiptDetail.status === "3" ||
396
+				this.receiptDetail.status === "4"
397
+			) {
398
+				uni.$u.toast("当前订单已经被收单或未收");
399
+				return;
400
+			}
401
+			uni.showModal({
402
+				title: "提示",
403
+				content: "确定要标记为未收吗?",
404
+				success: async (res) => {
405
+					if (res.confirm) {
406
+						try {
407
+							await uni.$u.api.oderForm({
408
+								status: "4",
409
+								id: this.receiptDetail.id,
410
+							});
411
+							uni.$u.toast("标记未收成功");
412
+							this.getDetail(); // 刷新详情
413
+						} catch (error) {
414
+							uni.$u.toast("操作失败");
416 415
 						}
417
-					},
418
-				});
419
-			},
420
-			// 撤销操作
421
-			async handleDelete() {
422
-				uni.showModal({
423
-					title: "提示",
424
-					content: "是否确定撤销?",
425
-					success: async (res) => {
426
-						if (res.confirm) {
427
-							try {
428
-								await uni.$u.api.deleteOrder([this.receiptDetail.id]);
429
-								uni.$u.toast("撤销成功");
430
-								// 撤销后返回上一页
431
-								setTimeout(() => {
432
-									uni.navigateBack();
433
-								}, 1500);
434
-							} catch (error) {
435
-								uni.$u.toast("撤销失败");
436
-							}
416
+					}
417
+				},
418
+			});
419
+		},
420
+		// 撤销操作
421
+		async handleDelete() {
422
+			uni.showModal({
423
+				title: "提示",
424
+				content: "是否确定撤销?",
425
+				success: async (res) => {
426
+					if (res.confirm) {
427
+						try {
428
+							await uni.$u.api.deleteOrder([this.receiptDetail.id]);
429
+							uni.$u.toast("撤销成功");
430
+							// 撤销后返回上一页
431
+							setTimeout(() => {
432
+								uni.navigateBack();
433
+							}, 1500);
434
+						} catch (error) {
435
+							uni.$u.toast("撤销失败");
437 436
 						}
438
-					},
439
-				});
440
-			},
441
-			// 初始化详情页
442
-			async handleInit() {
443
-				this.getDetail();
444
-				this.$getDicts("crm_form_category").then((res) => {
445
-					this.crmFormCategoryDict = res;
446
-				});
447
-				this.$getDicts("crm_form_tactic").then((res) => {
448
-					this.crmFormTacticDict = res;
449
-				});
450
-				this.$getDicts("crm_form_state").then((res) => {
451
-					this.crmFormStateDict = res;
452
-				});
453
-				this.$getDicts("crm_form_status").then((res) => {
454
-					this.crmHandelStatusDict = res;
455
-				});
456
-				uni.$u.api
457
-					.getClueTagGroupVoList({
458
-						tagGroupApplication: "2",
459
-					})
460
-					.then(({
461
-						data
462
-					}) => {
463
-						this.clueTagGroupVoList = data;
464
-					});
465
-			},
466
-			getDetail() {
467
-				uni.$u.api
468
-					.getClueSendFormVoByOrderId({
469
-						id: this.orderId,
470
-					})
471
-					.then((res) => {
472
-						this.receiptDetail = res.data;
473
-						this.checkTags = this.receiptDetail.tags ?
474
-							this.receiptDetail.tags.map((v) => v.id) :
475
-							[];
476
-					});
477
-			},
437
+					}
438
+				},
439
+			});
478 440
 		},
479
-		created() {
480
-			this.handleInit();
481
-			uni.$on('updateSendFormSuccess', () => {
482
-				this.getDetail();
441
+		// 初始化详情页
442
+		async handleInit() {
443
+			this.getDetail();
444
+			this.$getDicts("crm_form_category").then((res) => {
445
+				this.crmFormCategoryDict = res;
446
+			});
447
+			this.$getDicts("crm_form_tactic").then((res) => {
448
+				this.crmFormTacticDict = res;
449
+			});
450
+			this.$getDicts("crm_form_state").then((res) => {
451
+				this.crmFormStateDict = res;
483 452
 			});
453
+			this.$getDicts("crm_form_status").then((res) => {
454
+				this.crmHandelStatusDict = res;
455
+			});
456
+			uni.$u.api
457
+				.getClueTagGroupVoList({
458
+					tagGroupApplication: "2",
459
+				})
460
+				.then(({
461
+					data
462
+				}) => {
463
+					this.clueTagGroupVoList = data;
464
+				});
484 465
 		},
485
-		beforeDestroy() {
486
-			uni.$off('updateSendFormSuccess');
487
-		}
488
-	};
466
+		getDetail() {
467
+			uni.$u.api
468
+				.getClueSendFormVoByOrderId({
469
+					id: this.orderId,
470
+				})
471
+				.then((res) => {
472
+					this.receiptDetail = res.data;
473
+					this.checkTags = this.receiptDetail.tags ?
474
+						this.receiptDetail.tags.map((v) => v.id) :
475
+						[];
476
+				});
477
+		},
478
+	},
479
+	created() {
480
+		this.handleInit();
481
+		uni.$on('updateSendFormSuccess', () => {
482
+			this.getDetail();
483
+		});
484
+	},
485
+	beforeDestroy() {
486
+		uni.$off('updateSendFormSuccess');
487
+	}
488
+};
489 489
 </script>
490 490
 
491 491
 <style lang="scss" scoped>
492
-	.clueTagsSelect {
493
-		height: 0;
494
-		overflow: hidden;
495
-	}
492
+.clueTagsSelect {
493
+	height: 0;
494
+	overflow: hidden;
495
+}
496 496
 
497
-	.clue_tag_wrap {
498
-		display: flex;
499
-		align-items: center;
500
-		background-color: #fff;
501
-		padding: 0 10px;
502
-		margin: 20px 0;
503
-		flex-wrap: wrap;
504
-		min-height: 50px;
497
+.clue_tag_wrap {
498
+	display: flex;
499
+	align-items: center;
500
+	background-color: #fff;
501
+	padding: 0 10px;
502
+	margin: 20px 0;
503
+	flex-wrap: wrap;
504
+	min-height: 50px;
505 505
 
506
-		.clue_tag_add_btn {
507
-			font-size: 14px;
508
-			color: #108cff;
509
-		}
506
+	.clue_tag_add_btn {
507
+		font-size: 14px;
508
+		color: #108cff;
510 509
 	}
510
+}
511 511
 
512
-	.clue_state_wrap {
513
-		background-color: #fff;
514
-		padding: 10px;
515
-		margin-bottom: 20px;
516
-		display: flex;
517
-		align-items: center;
512
+.clue_state_wrap {
513
+	background-color: #fff;
514
+	padding: 10px;
515
+	margin-bottom: 20px;
516
+	display: flex;
517
+	align-items: center;
518 518
 
519
-		.top_left {
520
-			font-size: 16px;
521
-			flex: 0 0 50px;
522
-		}
519
+	.top_left {
520
+		font-size: 16px;
521
+		flex: 0 0 50px;
522
+	}
523 523
 
524
-		.steps_wrap {
525
-			flex: 1;
526
-		}
524
+	.steps_wrap {
525
+		flex: 1;
527 526
 	}
527
+}
528 528
 
529
-	.order_action_wrap {
530
-		padding: 10px;
531
-		margin: 15px 0;
532
-		background: #fff;
533
-		display: flex;
534
-		align-items: center;
529
+.order_action_wrap {
530
+	padding: 10px;
531
+	margin: 15px 0;
532
+	background: #fff;
533
+	display: flex;
534
+	align-items: center;
535 535
 
536
-		.action_title {
537
-			font-size: 16px;
538
-			flex: 0 0 50px;
539
-		}
536
+	.action_title {
537
+		font-size: 16px;
538
+		flex: 0 0 50px;
539
+	}
540 540
 
541
-		.last_status {
542
-			color: #c0c0c7;
543
-			font-size: 14px;
544
-		}
541
+	.last_status {
542
+		color: #c0c0c7;
543
+		font-size: 14px;
544
+	}
545 545
 
546
-		.action_buttons {
547
-			display: grid;
548
-			grid-template-columns: repeat(2, 1fr);
549
-			gap: 10px;
546
+	.action_buttons {
547
+		display: grid;
548
+		grid-template-columns: repeat(2, 1fr);
549
+		gap: 10px;
550 550
 
551
-			::v-deep .u-button {
552
-				height: 30px !important;
553
-				font-size: 12px !important;
554
-				border-radius: 8px !important;
555
-				border: 1px solid #e2e8f0 !important;
556
-				background: #ffffff !important;
557
-				color: #2d3748 !important;
558
-				font-weight: 500 !important;
559
-				box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1) !important;
560
-				transition: all 0.3s ease !important;
551
+		::v-deep .u-button {
552
+			height: 30px !important;
553
+			font-size: 12px !important;
554
+			border-radius: 8px !important;
555
+			border: 1px solid #e2e8f0 !important;
556
+			background: #ffffff !important;
557
+			color: #2d3748 !important;
558
+			font-weight: 500 !important;
559
+			box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1) !important;
560
+			transition: all 0.3s ease !important;
561 561
 
562
-				&.u-button--success {
563
-					background: #ffd025 !important;
564
-					color: white !important;
565
-					border-color: #ffd025 !important;
566
-				}
562
+			&.u-button--success {
563
+				background: #ffd025 !important;
564
+				color: white !important;
565
+				border-color: #ffd025 !important;
566
+			}
567 567
 
568
-				// 特别样式化不同按钮类型
569
-				&.u-button--primary {
570
-					background: #35dbd9 !important;
571
-					color: white !important;
572
-					border-color: #35dbd9 !important;
573
-				}
568
+			// 特别样式化不同按钮类型
569
+			&.u-button--primary {
570
+				background: #35dbd9 !important;
571
+				color: white !important;
572
+				border-color: #35dbd9 !important;
573
+			}
574 574
 
575
-				&.u-button--warning {
576
-					background: #ba9fb0 !important;
577
-					color: white !important;
578
-					border-color: #ba9fb0 !important;
579
-				}
575
+			&.u-button--warning {
576
+				background: #ba9fb0 !important;
577
+				color: white !important;
578
+				border-color: #ba9fb0 !important;
579
+			}
580 580
 
581
-				&.u-button--error {
582
-					background: #e53e3e !important;
583
-					color: white !important;
584
-					border-color: #e53e3e !important;
585
-				}
581
+			&.u-button--error {
582
+				background: #e53e3e !important;
583
+				color: white !important;
584
+				border-color: #e53e3e !important;
586 585
 			}
587 586
 		}
588 587
 	}
588
+}
589 589
 
590
-	.clueDetail_tabber {
591
-		::v-deep .u-tabbar__content {
592
-			background: #108cff;
593
-			border-top-right-radius: 10px;
594
-			border-top-left-radius: 10px;
595
-		}
590
+.clueDetail_tabber {
591
+	::v-deep .u-tabbar__content {
592
+		background: #108cff;
593
+		border-top-right-radius: 10px;
594
+		border-top-left-radius: 10px;
596 595
 	}
596
+}
597 597
 
598
-	.clueDetail_wrap {
599
-		.telPhone {
600
-			display: flex;
601
-			background: #fff;
602
-			padding: 20px;
603
-			justify-content: space-between;
598
+.clueDetail_wrap {
599
+	.telPhone {
600
+		display: flex;
601
+		background: #fff;
602
+		padding: 20px;
603
+		justify-content: space-between;
604 604
 
605
-			.left {
606
-				display: flex;
607
-			}
605
+		.left {
606
+			display: flex;
607
+		}
608 608
 
609
-			.copy_btn {
610
-				color: #4fa5fe;
611
-				margin-left: 10px;
612
-			}
609
+		.copy_btn {
610
+			color: #4fa5fe;
611
+			margin-left: 10px;
613 612
 		}
613
+	}
614 614
 
615
-		.clueDetail_top_info {
616
-			display: flex;
617
-			flex-wrap: wrap;
618
-			background-color: #ffffff;
619
-			padding-top: 20px;
620
-			margin: 18px 0;
615
+	.clueDetail_top_info {
616
+		display: flex;
617
+		flex-wrap: wrap;
618
+		background-color: #ffffff;
619
+		padding-top: 20px;
620
+		margin: 18px 0;
621 621
 
622
-			.top_info_item {
623
-				width: 33.33%;
624
-				text-align: center;
625
-				margin-bottom: 20px;
622
+		.top_info_item {
623
+			width: 33.33%;
624
+			text-align: center;
625
+			margin-bottom: 20px;
626 626
 
627
-				.top {
628
-					font-size: 15px;
629
-					color: #202020;
630
-					margin-bottom: 5px;
631
-					font-weight: bold;
632
-				}
627
+			.top {
628
+				font-size: 15px;
629
+				color: #202020;
630
+				margin-bottom: 5px;
631
+				font-weight: bold;
632
+			}
633 633
 
634
-				.bottom {
635
-					font-size: 15px;
636
-					color: #c0c0c7;
637
-				}
634
+			.bottom {
635
+				font-size: 15px;
636
+				color: #c0c0c7;
638 637
 			}
639 638
 		}
640 639
 	}
640
+}
641 641
 </style>

+ 7 - 7
pages/orderDetail/tabs/receiptFormList/receiptFormList.vue

@@ -7,7 +7,7 @@
7 7
 			<u-empty text="暂无收单数据"></u-empty>
8 8
 		</view>
9 9
 		<view v-else class="card_list">
10
-			<view class="card_item" v-for="(row) in receiptFormList" :key="row.id" >
10
+			<view class="card_item" v-for="(row) in receiptFormList" :key="row.id">
11 11
 				<view class="card_header">
12 12
 					<view class="card_title">{{ row.item || '-' }}</view>
13 13
 					<view class="card_actions">
@@ -44,7 +44,7 @@ export default {
44 44
 	props: {
45 45
 		receiptDetail: {
46 46
 			type: Object,
47
-			default: () => {}
47
+			default: () => { }
48 48
 		},
49 49
 		sendFormId: {
50 50
 			type: [Number, String],
@@ -102,7 +102,7 @@ export default {
102 102
 		/** 修改按钮操作 */
103 103
 		async handleUpdate(row) {
104 104
 			uni.navigateTo({
105
-			  url: `/pages/receiptForm/index?orderId=${this.sendFormId}&clueId=${this.clueId}&receiptId=${row.id}`,
105
+				url: `/pages/receiptForm/index?orderId=${this.sendFormId}&clueId=${this.clueId}&receiptId=${row.id}`,
106 106
 			});
107 107
 		},
108 108
 
@@ -136,12 +136,12 @@ export default {
136 136
 	},
137 137
 	created() {
138 138
 		this.getList();
139
-		uni.$on('addReceiptFormSuccess',()=>{
139
+		uni.$on('addReceiptFormSuccess', () => {
140 140
 			this.getList();
141 141
 		});
142 142
 	},
143
-	beforeDestroy(){
144
-		uni.$off('addReceiptFormSuccess');  
143
+	beforeDestroy() {
144
+		uni.$off('addReceiptFormSuccess');
145 145
 	}
146 146
 }
147 147
 </script>
@@ -206,7 +206,7 @@ export default {
206 206
 .info_value {
207 207
 	color: #202020;
208 208
 	flex: 1;
209
-	
209
+
210 210
 	&.highlight {
211 211
 		color: #f56c6c;
212 212
 		font-weight: bold;

+ 25 - 60
pages/orderDetail/tabs/uploadFile/index.vue

@@ -14,43 +14,23 @@
14 14
 		<view class="fileList_wrap" v-if="!loading && dataList.length > 0">
15 15
 			<view class="file_item_wrap" v-if="imgList.length > 0">
16 16
 				<view class="item_title">图片文件:</view>
17
-				<mk-upload 
18
-					:imgList="imgList" 
19
-					@onDelete="handleDelFile" 
20
-					:controlShow="false" 
21
-					type="image"
22
-					@onPreviewTake="handlePreviewImage"
23
-				></mk-upload>
17
+				<mk-upload :imgList="imgList" @onDelete="handleDelFile" :controlShow="false" type="image"
18
+					@onPreviewTake="handlePreviewImage"></mk-upload>
24 19
 			</view>
25 20
 			<view class="file_item_wrap" v-if="recordList.length > 0">
26 21
 				<view class="item_title">录音文件:</view>
27
-				<mk-upload 
28
-					:imgList="recordList" 
29
-					@onDelete="handleDelFile" 
30
-					:controlShow="false" 
31
-					type="record" 
32
-					@onPreviewTake="handlePreviewRecord"
33
-				></mk-upload>
22
+				<mk-upload :imgList="recordList" @onDelete="handleDelFile" :controlShow="false" type="record"
23
+					@onPreviewTake="handlePreviewRecord"></mk-upload>
34 24
 			</view>
35 25
 			<view class="file_item_wrap" v-if="videoList.length > 0">
36 26
 				<view class="item_title">视频文件:</view>
37
-				<mk-upload 
38
-					:imgList="videoList" 
39
-					@onDelete="handleDelFile" 
40
-					:controlShow="false" 
41
-					type="video"
42
-					@onPreviewTake="handlePreviewVideo"
43
-				></mk-upload>
27
+				<mk-upload :imgList="videoList" @onDelete="handleDelFile" :controlShow="false" type="video"
28
+					@onPreviewTake="handlePreviewVideo"></mk-upload>
44 29
 			</view>
45 30
 			<view class="file_item_wrap" v-if="otherList.length > 0">
46 31
 				<view class="item_title">其他文件:</view>
47
-				<mk-upload 
48
-					:imgList="otherList" 
49
-					@onDelete="handleDelFile" 
50
-					:controlShow="false" 
51
-					type="file"
52
-					@onPreviewTake="handlePreviewFile"
53
-				></mk-upload>
32
+				<mk-upload :imgList="otherList" @onDelete="handleDelFile" :controlShow="false" type="file"
33
+					@onPreviewTake="handlePreviewFile"></mk-upload>
54 34
 			</view>
55 35
 		</view>
56 36
 
@@ -65,31 +45,16 @@
65 45
 		</view>
66 46
 
67 47
 		<!-- 图片预览 -->
68
-		<u-image
69
-			ref="previewImg"
70
-			:src="previewImageSrc"
71
-			mode="widthFix"
72
-			v-if="previewImageSrc"
73
-			@click="previewImageSrc = ''"
74
-		></u-image>
48
+		<u-image ref="previewImg" :src="previewImageSrc" mode="widthFix" v-if="previewImageSrc"
49
+			@click="previewImageSrc = ''"></u-image>
75 50
 
76 51
 		<!-- 文件预览模态框 -->
77 52
 		<u-modal :show="showFileModal" :title="currentFile.fileName" @confirm="handleFileConfirm">
78 53
 			<view v-if="currentFile && currentFile.fileUrl" class="currentFile_wrap">
79
-				<audio 
80
-					style="text-align: left" 
81
-					:src="currentFile.fileUrl" 
82
-					:name="'点击播放'" 
83
-					controls
84
-					v-if="['wav','mp3','aac','wma'].includes(currentFile.fileSuffix)"
85
-				></audio>
86
-				<video 
87
-					:src="currentFile.fileUrl" 
88
-					mode="" 
89
-					class="currentFile_image" 
90
-					v-else-if="showFileModal" 
91
-					show-fullscreen-btn
92
-				></video>
54
+				<audio style="text-align: left" :src="currentFile.fileUrl" :name="'点击播放'" controls
55
+					v-if="['wav', 'mp3', 'aac', 'wma'].includes(currentFile.fileSuffix)"></audio>
56
+				<video :src="currentFile.fileUrl" mode="" class="currentFile_image" v-else-if="showFileModal"
57
+					show-fullscreen-btn></video>
93 58
 			</view>
94 59
 			<view v-else>
95 60
 				文件异常
@@ -122,7 +87,7 @@ import mkUpload from "@/components/mk-upload/mk-upload.vue"
122 87
 import upload from '@/mixins/upload';
123 88
 export default {
124 89
 	name: 'UploadFile',
125
-	mixins : [upload],
90
+	mixins: [upload],
126 91
 	components: {
127 92
 		mkUpload
128 93
 	},
@@ -135,13 +100,13 @@ export default {
135 100
 	},
136 101
 	computed: {
137 102
 		imgList() {
138
-			return this.dataList.filter(v => ['png','gif','bmp','jpg','jpeg','webp'].includes((v.fileSuffix || '').toLowerCase()));
103
+			return this.dataList.filter(v => ['png', 'gif', 'bmp', 'jpg', 'jpeg', 'webp'].includes((v.fileSuffix || '').toLowerCase()));
139 104
 		},
140 105
 		recordList() {
141
-			return this.dataList.filter(v => ['wav','mp3','aac','wma'].includes((v.fileSuffix || '').toLowerCase()));
106
+			return this.dataList.filter(v => ['wav', 'mp3', 'aac', 'wma'].includes((v.fileSuffix || '').toLowerCase()));
142 107
 		},
143 108
 		videoList() {
144
-			return this.dataList.filter(v => ['avi','mkv','mov','wmv','mp4'].includes((v.fileSuffix || '').toLowerCase()));
109
+			return this.dataList.filter(v => ['avi', 'mkv', 'mov', 'wmv', 'mp4'].includes((v.fileSuffix || '').toLowerCase()));
145 110
 		},
146 111
 		otherList() {
147 112
 			const list = this.imgList.concat(this.recordList).concat(this.videoList);
@@ -166,13 +131,13 @@ export default {
166 131
 		}
167 132
 	},
168 133
 	methods: {
169
-		async handleUploadSuccess(){
134
+		async handleUploadSuccess() {
170 135
 			await uni.$u.api.saveClueFile({
171
-				clueId : this.clueId,
172
-				list : this.uploadList,
136
+				clueId: this.clueId,
137
+				list: this.uploadList,
173 138
 				sourceId: this.sourceId,
174
-				type : this.type,
175
-				orderFileType : this.orderFileType
139
+				type: this.type,
140
+				orderFileType: this.orderFileType
176 141
 			});
177 142
 			uni.$u.toast("上传成功");
178 143
 			// 清空
@@ -356,10 +321,10 @@ export default {
356 321
 	padding: 0;
357 322
 	color: #666666;
358 323
 	font-size: 24rpx;
359
-	
324
+
360 325
 	.file_item_wrap {
361 326
 		margin-bottom: 20px;
362
-		
327
+
363 328
 		.item_title {
364 329
 			margin-bottom: 10px;
365 330
 			font-weight: bold;

+ 47 - 19
pages/orderDetailNew/components/orderDetailNewView.vue

@@ -2,7 +2,7 @@
2 2
     <view class="orderDetailNewView">
3 3
 
4 4
         <view class="page-item" v-show="activeIndex === 0">
5
-            <pageOne @handleNextClick="handleNextClick" :orderDetail="detail" />
5
+            <pageOne @handleNextClick="handleNextClick" :orderDetail="detail" :orderId="orderId" />
6 6
         </view>
7 7
         <view class="page-item" v-show="activeIndex === 1">
8 8
             <pageTwo @handleNextClick="handleNextClick" :orderDetail="detail" />
@@ -32,6 +32,14 @@ export default {
32 32
         detail: {
33 33
             type: Object,
34 34
             default: () => { },
35
+        },
36
+        topInfo: {
37
+            type: Object,
38
+            default: () => { },
39
+        },
40
+        orderId: {
41
+            type: String,
42
+            default: ''
35 43
         }
36 44
     },
37 45
     components: {
@@ -71,7 +79,7 @@ export default {
71 79
                 // "remark": ,    //发单备注,先不传
72 80
                 "params": this.detail.params,     //看接口文档
73 81
                 "id": this.detail.receiptId,
74
-                // "sendFormId": "25", //接单中心的id
82
+                "sendFormId": this.orderId, //接单中心的id,就是接单中心列表的id(发单id)
75 83
                 "clueId": this.detail.clueId,
76 84
                 "item": this.detail.item,
77 85
                 "brand": this.detail.brand,
@@ -84,7 +92,7 @@ export default {
84 92
                 // "freight": 30,         //运费page4加上
85 93
                 // "checkCodeFee": null,  //查码费
86 94
                 // "totalCost": "60230.00",   // 成本合计 =   运费 + 好处费 + 查码费 + 表款(支付总额) + 维修费。
87
-                // "sellingPrice": 90002,   //实际价格(售价)顶上tab里面的第三栏
95
+                "sellingPrice": this.topInfo.price.replace(/,/g, ''),   //实际价格(售价)顶上tab里面的第三栏
88 96
                 // "performance": "29772.00",  //sellingPrice - totalCost
89 97
                 // "receiptRemark":     //"收单之后还需再跟进", 先不传
90 98
                 // "repairAmount": null, //维修总金额 ,先不传
@@ -107,28 +115,48 @@ export default {
107 115
         // 保存实物图数据
108 116
         saveDetailImagesData() {
109 117
             // 上传二进制文件
110
-            this.allFroms.formOne.truePic.forEach(async (item) => {
111
-                await uni.$u.api.uploadFile(item);
112
-            })
113
-        },// 保存聊天图数据
114
-        saveChatPicData() {
115
-            this.allFroms.formOne.truePic.forEach(async (item) => {
116
-                await uni.$u.api.uploadFile(item);
117
-            })
118
-        },// 保存高清图数据
119
-        saveHighDefinitionPicData() {
120
-            this.allFroms.formOne.truePic.forEach(async (item) => {
121
-                await uni.$u.api.uploadFile(item);
122
-            })
118
+            // console.log("上传文件成功:1", this.allFroms.formOne.truePic)
119
+
120
+            // this.allFroms.formOne.truePic.forEach(async (item) => {
121
+            //     const res = await uni.$u.api.uploadFile(item);
122
+            //     console.log("上传文件成功:", res)
123
+            // })
123 124
         },
125
+        // // 保存聊天图数据
126
+        // saveChatPicData() {
127
+        //     this.allFroms.formOne.truePic.forEach(async (item) => {
128
+        //         await uni.$u.api.uploadFile(item);
129
+        //     })
130
+        // },
131
+        // // 保存高清图数据
132
+        // saveHighDefinitionPicData() {
133
+        //     this.allFroms.formOne.truePic.forEach(async (item) => {
134
+        //         await uni.$u.api.uploadFile(item);
135
+        //     })
136
+        // },
124 137
         handleNeedSave({ nowPage, form }) {
125
-            console.log("nowPage:", nowPage)
126
-            console.log("pageThreeForm:", form)
127 138
             this.pageThreeForm = form;
128 139
 
129 140
             //调用接口保存收单表单
130 141
             this.saveData();
131
-            this.saveDetailImagesData();
142
+            // this.saveDetailImagesData();
143
+
144
+            //保存数据之后调支付接口
145
+            this.pay();
146
+        },
147
+        //支付
148
+        async pay() {
149
+            // 开始支付
150
+            console.log('开始支付')
151
+            try {
152
+                const response = await uni.$u.api.saveOrderFileAndTransfer({
153
+                    id: this.orderId,
154
+                    clueId: this.detail.clueId//线索id
155
+                })
156
+                uni.$u.toast(response.msg || '支付成功')
157
+            } catch (error) {
158
+                uni.$u.toast(`支付失败:${response.msg}`)
159
+            }
132 160
         }
133 161
 
134 162
     }

+ 210 - 49
pages/orderDetailNew/components/pageOne.vue

@@ -5,7 +5,7 @@
5 5
                 <div class="page-itemOne-title">图片资料</div>
6 6
             </u-col>
7 7
             <u-col span="3.5">
8
-                <u-button size="small"
8
+                <u-button size="small" @click="copyAllImages"
9 9
                     style="border-radius: 20rpx;border-color: #007AFF;color: #007AFF;">复制全部图片</u-button>
10 10
             </u-col>
11 11
         </u-row>
@@ -15,9 +15,9 @@
15 15
             <view class="card-title">实物图</view>
16 16
             <view class="image-upload-container">
17 17
                 <view class="image-list">
18
-                    <view class="image-item" v-for="(item, index) in form.truePic" :key="'truePic-' + index">
19
-                        <pic-comp :src="item"></pic-comp>
20
-                        <view class="delete-btn" @click="deleteImage('truePic', index)">×</view>
18
+                    <view class="image-item" v-for="(item, index) in trueUploadList" :key="'truePic-' + index">
19
+                        <pic-comp :src="item.fileUrl"></pic-comp>
20
+                        <view class="delete-btn" @click="deleteImage('truePic', item)">×</view>
21 21
                     </view>
22 22
                     <view class="upload-btn" @click="uploadImage('truePic')">
23 23
                         <u-icon name="plus" size="40" color="#999"></u-icon>
@@ -31,9 +31,10 @@
31 31
             <view class="card-title">聊天记录</view>
32 32
             <view class="image-upload-container">
33 33
                 <view class="image-list">
34
-                    <view class="image-item" v-for="(item, index) in form.chatRecords" :key="'chatRecords-' + index">
35
-                        <pic-comp :src="item"></pic-comp>
36
-                        <view class="delete-btn" @click="deleteImage('chatRecords', index)">×</view>
34
+                    <view class="image-item" v-for="(item, index) in chatRecordsUploadList"
35
+                        :key="'chatRecords-' + index">
36
+                        <pic-comp :src="item.fileUrl"></pic-comp>
37
+                        <view class="delete-btn" @click="deleteImage('chatRecords', item)">×</view>
37 38
                     </view>
38 39
                     <view class="upload-btn" @click="uploadImage('chatRecords')">
39 40
                         <u-icon name="plus" size="40" color="#999"></u-icon>
@@ -95,6 +96,10 @@ export default {
95 96
         orderDetail: {
96 97
             type: Object,
97 98
             default: () => { },
99
+        },
100
+        orderId: {
101
+            type: String,
102
+            default: '',
98 103
         }
99 104
     },
100 105
     components: {
@@ -102,30 +107,35 @@ export default {
102 107
     },
103 108
     data() {
104 109
         return {
105
-            form: {
106
-                truePic: [],
107
-                chatRecords: [],
108
-            },
110
+            //展示的图片列表
111
+            trueUploadList: [],
112
+            chatRecordsUploadList: [],
113
+            // 待绑定的图片列表
114
+            bindList: [],
109 115
         }
110 116
     },
111
-    beforeMount() {
112
-        setTimeout(() => {
113
-            console.log('orderDetail', this.orderDetail);
114
-        }, 5000)
117
+    watch: {
118
+        // 监听 props 变化,触发请求
119
+        orderDetail: {
120
+            handler(newVal) {
121
+                if (newVal) { // 确保 props 有值再执行
122
+                    this.getList('2', '1');
123
+                    this.getList('2', '2');
124
+                }
125
+            }
126
+        }
115 127
     },
116 128
     methods: {
117
-        // 上传图片
129
+        // 选择图片
118 130
         uploadImage(type) {
119 131
             uni.chooseImage({
120
-                count: 9 - this.form[type].length, // 最多选择9张
132
+                count: 9, // 最多选择9张
121 133
                 sizeType: ['compressed'], // 压缩图片
122 134
                 sourceType: ['album', 'camera'], // 从相册选择或拍照
123 135
                 success: (res) => {
124 136
                     const tempFilePaths = res.tempFilePaths
125
-                    // 将图片路径添加到对应的数组中
126
-                    this.form[type] = [...this.form[type], ...tempFilePaths]
127
-                    // 这里可以添加上传到服务器的逻辑
128
-                    // this.uploadToServer(tempFilePaths, type)
137
+                    console.log('上传的图片路径:11', tempFilePaths)
138
+                    this.uploadToServer(tempFilePaths, type)
129 139
                 },
130 140
                 fail: (err) => {
131 141
                     console.error('选择图片失败:', err)
@@ -133,46 +143,133 @@ export default {
133 143
             })
134 144
         },
135 145
         // 删除图片
136
-        deleteImage(type, index) {
146
+        deleteImage(type, item) {
137 147
             uni.showModal({
138 148
                 title: '提示',
139 149
                 content: '确定要删除这张图片吗?',
140 150
                 success: (res) => {
141 151
                     if (res.confirm) {
142
-                        this.form[type].splice(index, 1)
152
+                        // 调接口删除
153
+                        console.log('现在要删除的文件文件是:', type, item.fileUrl, item.id)
154
+                        this.deleteImg(item.id)
155
+                        this.getList('2', '1');
156
+                        this.getList('2', '2');
143 157
                     }
144 158
                 }
145 159
             })
146 160
         },
147
-        // 上传到服务器(示例)
148
-        uploadToServer(filePaths, type) {
149
-            filePaths.forEach((filePath, index) => {
150
-                uni.uploadFile({
151
-                    url: 'your-upload-api-url', // 替换为实际的上传接口
152
-                    filePath: filePath,
153
-                    name: 'file',
154
-                    formData: {
155
-                        type: type
156
-                    },
157
-                    success: (uploadRes) => {
158
-                        const data = JSON.parse(uploadRes.data)
159
-                        // 上传成功后,将临时路径替换为服务器返回的路径
160
-                        const tempIndex = this.form[type].indexOf(filePath)
161
-                        if (tempIndex !== -1) {
162
-                            this.form[type][tempIndex] = data.url // 假设服务器返回data.url
163
-                        }
164
-                    },
165
-                    fail: (err) => {
166
-                        console.error('上传图片失败:', err)
167
-                    }
161
+        // 删除图片
162
+        async deleteImg(id) {
163
+            try {
164
+                await uni.$u.api.deleteClueFile([id])
165
+                uni.showToast({
166
+                    title: '删除成功',
167
+                    icon: 'success',
168
+                    duration: 2000
168 169
                 })
169
-            })
170
+            } catch (error) {
171
+                uni.showToast({
172
+                    title: '删除失败',
173
+                    icon: 'error',
174
+                    duration: 2000
175
+                })
176
+            }
177
+        },
178
+        // 上传到服务
179
+        async uploadToServer(filePaths, type) {
180
+            // 实际的上传逻辑
181
+            try {
182
+                //实物图的话就是2,聊天记录的话就是1
183
+                let p = type == 'truePic' ? '2' : type == 'chatRecords' ? '1' : ''
184
+                console.log('当前上传的图片类型是', p)
185
+                const res = await Promise.all(filePaths.map(filePath => this.uploadFile(filePath, p)));
186
+
187
+                // 绑定
188
+                this.bindOrder(type, p);
189
+
190
+                // 实物图的话传2
191
+                if (type == 'truePic') {
192
+                    // this.bindOrder('2', '2');
193
+                    this.getList('2', '2');
194
+                }
195
+                // 实物图的话聊天记录的话传1
196
+                if (type == 'chatRecords') {
197
+                    // 实物图的话聊天记录的话传1
198
+                    // this.bindOrder('2', '1');
199
+                    this.getList('2', '1');
200
+                }
201
+
202
+
203
+            } catch (error) {
204
+                console.error('上传失败:', error);
205
+                uni.$u.toast('上传失败');
206
+            }
207
+        },
208
+        //绑定订单
209
+        async bindOrder(type, orderFileType) {
210
+            const res = await uni.$u.api.saveClueFile({
211
+                clueId: this.orderDetail.clueId,//线索id
212
+                list: this.bindList,
213
+                sourceId: this.orderId,//订单id,sendformid
214
+                type: type,
215
+                orderFileType: orderFileType
216
+            });
217
+            uni.$u.toast("上传成功");
218
+            uni.hideLoading();
219
+            // 清空待绑定的图片列表
220
+            this.bindList = [];
221
+        },
222
+        // 上传文件
223
+        async uploadFile(fileUrl, orderFileType) {
224
+            try {
225
+                uni.showLoading({
226
+                    title: '上传中...',
227
+                    mask: true
228
+                });
229
+
230
+                console.log(111, fileUrl)
231
+                // 调用统一的上传接口
232
+                const { data } = await uni.$u.api.uploadFile(fileUrl);
233
+
234
+                const fileObj = {
235
+                    fileSize: data.fileSize,
236
+                    fileSuffix: data.fileSuffix,
237
+                    fileName: data.name,
238
+                    fileUrl: data.url,
239
+                    orderFileType: orderFileType
240
+                };
241
+
242
+
243
+
244
+                if (orderFileType == '2') {
245
+                    // this.trueUploadList.push(fileObj);
246
+                } else if (orderFileType == '1') {
247
+                    // this.chatRecordsUploadList.push(fileObj);
248
+                }
249
+                this.bindList.push(fileObj);
250
+
251
+            } catch (error) {
252
+                uni.hideLoading();
253
+                console.error('文件上传失败:', error);
254
+                uni.$u.toast('上传失败,请重试');
255
+            }
170 256
         },
257
+
171 258
         // 电话卡片点击事件
172 259
         handlePhoneClick() {
173 260
             console.log('电话卡片被点击', '电话号码:', this.orderDetail.phone)
174 261
             if (this.orderDetail.phone) {
175
-                //    稍后调用整个拨打电话的逻辑
262
+                //拨打电话
263
+                uni.makePhoneCall({
264
+                    phoneNumber: this.orderDetail.phone,
265
+                    success: () => {
266
+                        this.$store.commit("call/SET_FORM", {
267
+                            clueId: this.orderDetail.clueId,
268
+                            type: "3",
269
+                            callee: this.orderDetail.phone,
270
+                        });
271
+                    },
272
+                });
176 273
             } else {
177 274
                 uni.showToast({
178 275
                     title: '该订单暂时没有电话号码',
@@ -184,7 +281,16 @@ export default {
184 281
         handleWechatClick() {
185 282
             console.log('微信卡片被点击', '微信号:', this.orderDetail.wechat)
186 283
             if (this.orderDetail.wechat) {
187
-                //    稍后调用打开微信的逻辑
284
+                //复制微信号
285
+                uni.setClipboardData({
286
+                    data: this.orderDetail.wechat,
287
+                    success: () => {
288
+                        uni.showToast({
289
+                            title: '微信号已复制',
290
+                            icon: 'none'
291
+                        })
292
+                    }
293
+                })
188 294
             } else {
189 295
                 uni.showToast({
190 296
                     title: '该订单暂时没有微信号',
@@ -213,8 +319,63 @@ export default {
213 319
                 nowPage: 'formOne',
214 320
                 form: this.form,
215 321
             })
216
-        }
217
-    }
322
+        },
323
+        // 获取文件列表
324
+        async getList(type, orderFileType) {
325
+            console.log('获取文件列表', type, orderFileType)
326
+
327
+            try {
328
+                const params = {
329
+                    clueId: this.orderDetail.clueId,
330
+                    sourceId: this.orderId,
331
+                    type,
332
+                    orderFileType,
333
+                    isDuplicate: '1',//先传1
334
+                    pageNum: 1,
335
+                    pageSize: 1000 // 设置一个较大的值以获取所有数据
336
+                }
337
+                const response = await uni.$u.api.selectClueFileByDto(params)
338
+                if (orderFileType == '1') {
339
+                    this.trueUploadList = response.rows || []
340
+                } else if (orderFileType == '2') {
341
+                    this.chatRecordsUploadList = response.rows || []
342
+                }
343
+            } catch (error) {
344
+                uni.$u.toast(`获取列表失败:${error.message}`)
345
+                this.trueUploadList = []
346
+                this.chatRecordsUploadList = []
347
+            }
348
+        },
349
+
350
+        //一键复制
351
+        copyAllImages() {
352
+            // 合并所有图片
353
+            const allImages = [...this.trueUploadList, ...this.chatRecordsUploadList];
354
+            //取出所有图的url
355
+            const allUrls = allImages.map(item => item.fileUrl);
356
+            console.log('所有图片:', allUrls)
357
+            console.log('合并后的图片列表:', allUrls)
358
+            if (allUrls.length > 0) {
359
+                // 复制到剪贴板
360
+                uni.setClipboardData({
361
+                    data: JSON.stringify(allUrls),
362
+                    success: () => {
363
+                        uni.showToast({
364
+                            title: '所有图片已复制',
365
+                            icon: 'none'
366
+                        })
367
+                    }
368
+                })
369
+            } else {
370
+                uni.showToast({
371
+                    title: '没有图片可复制',
372
+                    icon: 'none'
373
+                })
374
+            }
375
+        },
376
+
377
+    },
378
+
218 379
 }
219 380
 </script>
220 381
 <style scoped lang="scss">

+ 34 - 99
pages/orderDetailNew/components/pageTwo.vue

@@ -197,49 +197,7 @@ export default {
197 197
                 }
198 198
             });
199 199
         },
200
-        // 图片预览方法
201
-        previewImageHandler(image, type) {
202
-            let currentIndex = 0;
203
-            let imageList = [];
204
-
205
-            // 根据类型获取对应的图片数组
206
-            if (type === 'photoTips') {
207
-                imageList = this.photoTipsImages;
208
-                currentIndex = imageList.indexOf(image);
209
-            } else if (type === 'face2face') {
210
-                imageList = this.face2faceImages;
211
-                currentIndex = imageList.indexOf(image);
212
-            }
213 200
 
214
-            // 使用uni-app的图片预览API
215
-            uni.previewImage({
216
-                current: currentIndex, // 当前预览图片的索引
217
-                urls: imageList, // 需要预览的图片链接列表
218
-                loop: true, // 是否可循环预览
219
-                longPressActions: {
220
-                    itemList: ['保存图片'],
221
-                    success: function (data) {
222
-                        // 保存图片到相册
223
-                        uni.saveImageToPhotosAlbum({
224
-                            filePath: imageList[data.tapIndex],
225
-                            success: function () {
226
-                                uni.showToast({
227
-                                    title: '保存成功',
228
-                                    icon: 'success'
229
-                                });
230
-                            },
231
-                            fail: function (err) {
232
-                                console.error('保存图片失败:', err);
233
-                                uni.showToast({
234
-                                    title: '保存失败',
235
-                                    icon: 'none'
236
-                                });
237
-                            }
238
-                        });
239
-                    }
240
-                }
241
-            });
242
-        },
243 201
 
244 202
         // 价格输入回调
245 203
         onPriceInput(e) {
@@ -258,66 +216,10 @@ export default {
258 216
             this.approvedPrice = newPrice;
259 217
         },
260 218
 
261
-        // 上传高清细节图
262
-        uploadDetailImage() {
263
-            uni.chooseImage({
264
-                count: 9 - this.detailImages.length, // 最多选择9张
265
-                sizeType: ['compressed'], // 压缩图片
266
-                sourceType: ['album', 'camera'], // 从相册选择或拍照
267
-                success: (res) => {
268
-                    const tempFilePaths = res.tempFilePaths;
269
-                    // 将图片路径添加到数组中
270
-                    this.detailImages = [...this.detailImages, ...tempFilePaths];
271
-                },
272
-                fail: (err) => {
273
-                    console.error('选择图片失败:', err);
274
-                    uni.showToast({
275
-                        title: '选择图片失败',
276
-                        icon: 'none'
277
-                    });
278
-                }
279
-            });
280
-        },
281
-
282
-        // 删除高清细节图
283
-        deleteDetailImage(index) {
284
-            uni.showModal({
285
-                title: '提示',
286
-                content: '确定要删除这张图片吗?',
287
-                success: (res) => {
288
-                    if (res.confirm) {
289
-                        this.detailImages.splice(index, 1);
290
-                    }
291
-                }
292
-            });
293
-        },
294 219
 
295 220
         // 复制所有高清细节图链接
296 221
         copyAllDetailImages() {
297
-            if (this.detailImages.length === 0) {
298
-                uni.showToast({
299
-                    title: '暂无图片可复制',
300
-                    icon: 'none'
301
-                });
302
-                return;
303
-            }
304 222
 
305
-            const imageUrls = this.detailImages.join('\n');
306
-            uni.setClipboardData({
307
-                data: imageUrls,
308
-                success: () => {
309
-                    uni.showToast({
310
-                        title: '复制成功',
311
-                        icon: 'success'
312
-                    });
313
-                },
314
-                fail: () => {
315
-                    uni.showToast({
316
-                        title: '复制失败',
317
-                        icon: 'none'
318
-                    });
319
-                }
320
-            });
321 223
         },
322 224
 
323 225
         // 下一步按钮点击事件
@@ -354,7 +256,40 @@ export default {
354 256
                 nowPage: 'formTwo',
355 257
                 form: result,
356 258
             })
357
-        }
259
+        },
260
+        //获取文件列表
261
+        async getList() {
262
+            console.log('获取文件列表', type, orderFileType)
263
+
264
+            try {
265
+                const params = {
266
+                    clueId: this.orderDetail.clueId,
267
+                    sourceId: this.orderId,
268
+                    type: '2',
269
+                    orderFileType: '3',
270
+                    isDuplicate: '1',//先传1
271
+                    pageNum: 1,
272
+                    pageSize: 1000 // 设置一个较大的值以获取所有数据
273
+                }
274
+                const response = await uni.$u.api.selectClueFileByDto(params)
275
+                this.detailImages = response.rows || []
276
+            } catch (error) {
277
+                uni.$u.toast(`获取列表失败:${error.message}`)
278
+            }
279
+        },
280
+        // 上传高清细节图
281
+        uploadDetailImage() {
282
+
283
+        },
284
+        // 删除高清细节图
285
+        deleteDetailImage(index) {
286
+            uni.showModal({
287
+                title: '提示',
288
+                content: '确定要删除这张图片吗?',
289
+                success: (res) => {
290
+                }
291
+            });
292
+        },
358 293
     }
359 294
 };
360 295
 </script>

+ 1 - 1
pages/orderDetailNew/index.vue

@@ -19,7 +19,7 @@
19 19
             </template>
20 20
         </u-navbar>
21 21
 
22
-        <orderDetailNewView :detail="receiptDetail" />
22
+        <orderDetailNewView :detail="receiptDetail" :topInfo="topInfo" :orderId="orderId" />
23 23
 
24 24
         <!-- 通用模态窗 -->
25 25
         <custom-modal :visible="modalVisible" :title="modalConfig.title" :value="modalConfig.value"

+ 214 - 0
pages/pagereceivecenter/compounts/orderCard.vue

@@ -0,0 +1,214 @@
1
+<script>
2
+export default {
3
+    props: {
4
+        order: {
5
+            type: Object,
6
+            default: () => ({})
7
+        }
8
+    },
9
+    methods: {
10
+        handerBtnClick(btnType, order) {
11
+            this.$emit('handleBtnClick', btnType, order);
12
+        }
13
+    }
14
+}
15
+
16
+</script>
17
+
18
+
19
+
20
+
21
+<template>
22
+    <view class="orderCard">
23
+        <view class="bandAndPrice">
24
+            <view class="bandName">{{ order.itemBrand || '暂无品牌' }}</view>
25
+            <view class="price">¥{{ order.priceRange }}</view>
26
+        </view>
27
+
28
+        <view class="mainLind">
29
+            <view class="mainLindImg">
30
+                <image :src="'/static/acceptOrder/orderCardPic.jpg'" alt="" />
31
+            </view>
32
+            <view class="mainLindInfo">
33
+                <view class="itemName">{{ order.item || '暂无项目' }}</view>
34
+                <view>发单人:{{ order.createNickName || '未知' }}</view>
35
+                <view>{{ order.sendDate || '暂无时间' }}</view>
36
+            </view>
37
+        </view>
38
+
39
+        <view class="tags">
40
+            <view class="tag" v-for="(tag, index) in order.tags" :key="index"
41
+                :style="{ backgroundColor: tag.color, opacity: 0.8 }">
42
+                {{ tag.name }}</view>
43
+
44
+        </view>
45
+
46
+        <view class="Btns">
47
+
48
+            <view class="btnGroup"
49
+                v-if="order && (order.status == '1' || order.status == null || order.status === undefined)">
50
+                <view class="card-button" @click="handerBtnClick('acceptOrder', order)">立即接单</view>
51
+                <view class=" card-button isBusy" @click="handerBtnClick('isBusy', order)">在忙</view>
52
+            </view>
53
+
54
+            <view class="btnGroup"
55
+                v-if="order && (order.status == '2' || order.status == null || order.status === undefined)">
56
+                <view class="card-button willFollow" @click="handerBtnClick('willFollow', order)">待跟进</view>
57
+                <view class="card-button isBusy" @click="handerBtnClick('tag', order)">打标签</view>
58
+            </view>
59
+
60
+            <view class="btnGroup"
61
+                v-if="order && (order.status == '3' || order.status == null || order.status === undefined)">
62
+                <view class="card-button share" @click="handerBtnClick('share', order)">一键分享</view>
63
+            </view>
64
+
65
+            <view class="btnGroup"
66
+                v-if="order && (order.status == '4' || order.status == null || order.status === undefined)">
67
+                <view class="card-button oneFollow" @click="handerBtnClick('oneFollow', order)">待跟进</view>
68
+            </view>
69
+
70
+        </view>
71
+    </view>
72
+</template>
73
+
74
+
75
+
76
+
77
+<style scoped lang="scss">
78
+/* 订单卡片主容器 */
79
+.orderCard {
80
+    box-sizing: border-box;
81
+    width: 95%;
82
+    background-color: #fff;
83
+    margin: 20rpx auto;
84
+    border-radius: 20rpx;
85
+    padding: 20rpx;
86
+}
87
+
88
+/* 品牌和价格区域 */
89
+.orderCard .bandAndPrice {
90
+    display: flex;
91
+    justify-content: space-between;
92
+    align-items: center;
93
+}
94
+
95
+/* 品牌名称 */
96
+.orderCard .bandAndPrice .bandName {
97
+    font-size: 20rpx;
98
+    font-weight: 700;
99
+    border: 2px solid #2563EB;
100
+    padding: 6rpx 12rpx;
101
+    border-radius: 15rpx;
102
+    background-color: #EFF6FF;
103
+    color: #2563EB;
104
+}
105
+
106
+/* 价格 */
107
+.orderCard .bandAndPrice .price {
108
+    font-size: 30rpx;
109
+    font-weight: 700;
110
+}
111
+
112
+/* 主要内容行 */
113
+.orderCard .mainLind {
114
+    margin-top: 10rpx;
115
+    display: flex;
116
+    justify-content: space-between;
117
+    align-items: center;
118
+    gap: 20rpx;
119
+}
120
+
121
+/* 主要内容行图片容器 */
122
+.orderCard .mainLind .mainLindImg image {
123
+    width: 150rpx;
124
+    height: 150rpx;
125
+    border-radius: 20rpx;
126
+}
127
+
128
+/* 主要内容行信息容器 */
129
+.orderCard .mainLind .mainLindInfo {
130
+    flex: 1;
131
+    display: flex;
132
+    flex-direction: column;
133
+    gap: 10rpx;
134
+    font-size: 24rpx;
135
+    color: #6b7280;
136
+}
137
+
138
+/* 商品名称 */
139
+.orderCard .mainLind .mainLindInfo .itemName {
140
+    font-size: 30rpx;
141
+    font-weight: 700;
142
+    color: #374751;
143
+}
144
+
145
+/* 标签区域 */
146
+.orderCard .tags {
147
+    display: flex;
148
+    gap: 10rpx;
149
+}
150
+
151
+/* 单个标签 */
152
+.orderCard .tags .tag {
153
+    font-size: 20rpx;
154
+    font-weight: 700;
155
+    padding: 6rpx 12rpx;
156
+    border-radius: 15rpx;
157
+    background-color: #EFF6FF;
158
+    color: #fff;
159
+}
160
+
161
+/* 按钮区域 */
162
+.orderCard .Btns {
163
+    margin-top: 10rpx;
164
+}
165
+
166
+/* 按钮组 */
167
+.orderCard .Btns .btnGroup {
168
+    display: flex;
169
+    justify-content: space-between;
170
+    align-items: center;
171
+    gap: 20rpx;
172
+}
173
+
174
+/* 卡片按钮基础样式 */
175
+.orderCard .Btns .btnGroup .card-button {
176
+    font-size: 24rpx;
177
+    font-weight: 700;
178
+    border: 2rpx solid #2563EB;
179
+    padding: 6rpx 12rpx;
180
+    border-radius: 15rpx;
181
+    background-color: #2563EB;
182
+    color: #fff;
183
+    width: 45%;
184
+    text-align: center;
185
+    cursor: pointer;
186
+    height: 60rpx;
187
+    line-height: 60rpx;
188
+}
189
+
190
+/* 忙碌状态按钮 */
191
+.orderCard .Btns .btnGroup .card-button.isBusy {
192
+    background-color: #fff;
193
+    color: #6B7280;
194
+    border-color: #6B7280;
195
+}
196
+
197
+/* 待跟进状态按钮 */
198
+.orderCard .Btns .btnGroup .card-button.willFollow {
199
+    background-color: #EFF6FF;
200
+    color: #2563EB;
201
+}
202
+
203
+/* 分享按钮 */
204
+.orderCard .Btns .btnGroup .card-button.share {
205
+    width: 100%;
206
+}
207
+
208
+/* 单独跟进按钮 */
209
+.orderCard .Btns .btnGroup .card-button.oneFollow {
210
+    width: 100%;
211
+    background-color: #EFF6FF;
212
+    color: #2563EB;
213
+}
214
+</style>

+ 155 - 0
pages/pagereceivecenter/pagereceivecenter.vue

@@ -0,0 +1,155 @@
1
+<script>
2
+import orderCard from "./compounts/orderCard.vue";
3
+
4
+export default {
5
+    components: {
6
+        orderCard,
7
+    },
8
+    data() {
9
+        return {
10
+            orderList: [],
11
+            page: {
12
+                pageSize: 10,
13
+                pageNum: 1,
14
+                total: 0
15
+            },
16
+        }
17
+    },
18
+    onLoad() {
19
+        //初始调用
20
+        // this.getOrderList();
21
+        uni.navigateTo({
22
+            url: `/pages/orderDetailNew/index?orderId=5464&item=测试发单&type=undefined&clueId=1973381744953516033`,
23
+        })
24
+    },
25
+    methods: {
26
+        //获取列表数据
27
+        async getOrderList() {
28
+            try {
29
+                const result = await uni.$u.api.selectClueOrderFormList({
30
+                    pageSize: this.page.pageSize,
31
+                    pageNum: this.page.pageNum,
32
+                });
33
+
34
+                console.log('接单列表', result);
35
+                // 把数组按照status的大小排序,从小到大
36
+                result.rows.sort((a, b) => {
37
+                    return a.status - b.status;
38
+                })
39
+
40
+
41
+                this.orderList.push(...result.rows);
42
+                this.page.total = result.total;
43
+
44
+            } catch (error) {
45
+                console.error('接单列表接口调用失败:', error);
46
+                // 添加用户友好的错误提示
47
+                uni.$u.toast('获取订单列表失败,请稍后重试');
48
+            }
49
+        },
50
+
51
+        // 处理按钮点击事件
52
+        handleBtnClick(btnType, order) {
53
+
54
+            if (btnType == 'acceptOrder') {
55
+                //去接单
56
+                console.log('去接单', order)
57
+
58
+                //跳转接单form
59
+                uni.navigateTo({
60
+                    url: `/pages/orderDetailNew/index?orderId=${order.id}&item=${order.item}&type=${this.type}&clueId=${order.clueId}`,
61
+                })
62
+            } else if (btnType == 'isBusy') {
63
+                //在忙
64
+                console.log('在忙', order)
65
+
66
+
67
+                //当前订单移动到末尾
68
+                this.orderList.push(this.orderList.splice(this.orderList.indexOf(order), 1)[0]);
69
+
70
+
71
+            } else if (btnType == 'willFollow') {
72
+                //待跟进
73
+                console.log('待跟进', order)
74
+            } else if (btnType == 'tag') {
75
+                //打标签
76
+                console.log('打标签', order)
77
+            } else if (btnType == 'share') {
78
+                //一键分享
79
+                console.log('一键分享', order)
80
+            } else if (btnType == 'oneFollow') {
81
+                //待跟进
82
+                console.log('待跟进', order)
83
+            }
84
+        },
85
+
86
+        //滑动加载
87
+        scrolltolower() {
88
+            console.log('到底了');
89
+            if (this.orderList.length >= this.page.total) {
90
+                return uni.$u.toast('没有更多了');
91
+            }
92
+            this.page.pageNum++;
93
+            this.getOrderList();
94
+        },
95
+
96
+    }
97
+}
98
+</script>
99
+
100
+<template>
101
+    <view class="container">
102
+        <u-navbar title="接单中心" :autoBack="true" :placeholder="true" v-hideNav></u-navbar>
103
+
104
+        <view class="scrollViewContainer">
105
+            <scroll-view class="scrollView" scroll-y @scrolltolower="scrolltolower">
106
+                <transition-group name="order-move" tag="div">
107
+                    <orderCard v-for="item in orderList" :key="item.receiptId + item.id" :order="item"
108
+                        @handleBtnClick="handleBtnClick">
109
+                    </orderCard>
110
+                </transition-group>
111
+                <view class="hasMore">
112
+                    {{ orderList.length >= page.total ? '没有更多了~' : '向下滑动加载更多~' }}
113
+                </view>
114
+            </scroll-view>
115
+        </view>
116
+
117
+
118
+
119
+
120
+
121
+    </view>
122
+</template>
123
+
124
+<style scoped lang="scss">
125
+.hasMore {
126
+    text-align: center;
127
+    padding: 20rpx 0;
128
+    font-size: 24rpx;
129
+    color: #999;
130
+}
131
+
132
+.scrollViewContainer {
133
+    height: calc(100vh - 44px);
134
+}
135
+
136
+.scrollView {
137
+    height: 100%;
138
+}
139
+
140
+/* 订单移动动画 */
141
+.order-move-enter-active,
142
+.order-move-leave-active {
143
+    transition: all 0.5s ease;
144
+}
145
+
146
+.order-move-enter-from,
147
+.order-move-leave-to {
148
+    opacity: 0;
149
+    transform: translateY(30px);
150
+}
151
+
152
+.order-move-move {
153
+    transition: transform 0.5s ease;
154
+}
155
+</style>

+ 317 - 313
pages/person/index.vue

@@ -2,7 +2,7 @@
2 2
 	<view class="person_wrap">
3 3
 		<template v-if="userInfo.userId">
4 4
 			<view class="navbar-wrap">
5
-				<view class="column" :class="{fixed : isFixedTop}" :style="{background: background}" id="navbar">
5
+				<view class="column" :class="{ fixed: isFixedTop }" :style="{ background: background }" id="navbar">
6 6
 					<view class="left"></view>
7 7
 					<view style="font-size:36rpx" class="center">我的</view>
8 8
 					<view class="right" @click="handleSetting">
@@ -17,22 +17,24 @@
17 17
 						<u-avatar @click="handleAvatarClick" :src="$avatar(userInfo.avatar)" size="100rpx"></u-avatar>
18 18
 						<view class="info_wrap">
19 19
 							<view class="info_top">
20
-								<text class="follow_name">{{userInfo.userName}}</text>
21
-								<u-switch v-model="onlineStatus" active-value='0' inactive-value='1' :loading="onlineLoading" @change="changeOnlineStatus"></u-switch>
20
+								<text class="follow_name">{{ userInfo.userName }}</text>
21
+								<u-switch v-model="onlineStatus" active-value='0' inactive-value='1'
22
+									:loading="onlineLoading" @change="changeOnlineStatus"></u-switch>
22 23
 								<text class="identity">{{ onlineStatus === '0' ? '上线' : '下线' }}</text>
23 24
 							</view>
24 25
 							<view class="info_bottom">
25
-								<text>{{userInfo.phonenumber}}</text>
26
+								<text>{{ userInfo.phonenumber }}</text>
26 27
 							</view>
27 28
 						</view>
28 29
 					</view>
29
-					<view class="header_info_right"  @click="toPersonal">
30
+					<view class="header_info_right" @click="toPersonal">
30 31
 						<u-icon name="arrow-right" color="#aaa"></u-icon>
31 32
 					</view>
32 33
 				</view>
33 34
 				<view class="parson_menu_wrap">
34 35
 					<view class="parson_menu_list">
35
-						<navigator url="/pages/publicClue/index" open-type="switchTab" class="menu_item" hover-class="none">
36
+						<navigator url="/pages/publicClue/index" open-type="switchTab" class="menu_item"
37
+							hover-class="none">
36 38
 							<image src="@/static/parson/icon-wf.png" mode=""></image>
37 39
 							<text>销售公海</text>
38 40
 						</navigator>
@@ -40,11 +42,13 @@
40 42
 							<image src="@/static/parson/icon-myMessage.png" mode=""></image>
41 43
 							<text>我的消息</text>
42 44
 						</navigator>
43
-						<navigator url='/pages/acceptOrderOrder/index' open-type="navigate" class="menu_item" hover-class="none">
45
+						<navigator url='/pages/pagereceivecenter/pagereceivecenter' open-type="navigate"
46
+							class="menu_item" hover-class="none">
44 47
 							<image src="@/static/parson/icon-mycase.png" mode=""></image>
45 48
 							<text>接单中心</text>
46 49
 						</navigator>
47
-						<navigator url='/pages/privateClue/index' open-type="switchTab" class="menu_item" hover-class="none">
50
+						<navigator url='/pages/privateClue/index' open-type="switchTab" class="menu_item"
51
+							hover-class="none">
48 52
 							<image src="@/static/parson/clue.png" mode=""></image>
49 53
 							<text>销售线索</text>
50 54
 						</navigator>
@@ -60,366 +64,366 @@
60 64
 </template>
61 65
 
62 66
 <script>
63
-	import optionList from "./option/index.vue"
64
-	import permision from "@/js_sdk/wa-permission/permission.js";
65
-	export default {
66
-		components: {
67
-			optionList
67
+import optionList from "./option/index.vue"
68
+import permision from "@/js_sdk/wa-permission/permission.js";
69
+export default {
70
+	components: {
71
+		optionList
72
+	},
73
+	data() {
74
+		return {
75
+			onlineLoading: false,
76
+			switchSystemShow: false,
77
+			navbarInitTop: 0, //导航栏初始化距顶部的距离
78
+			isFixedTop: true, //是否固定顶部
79
+			background: "", // 为了实现渐变背景颜色
80
+		};
81
+	},
82
+	computed: {
83
+		userInfo() {
84
+			return this.$store.state.user.userInfo;
68 85
 		},
69
-		data() {
70
-			return {
71
-				onlineLoading : false,
72
-				switchSystemShow: false,
73
-				navbarInitTop: 0, //导航栏初始化距顶部的距离
74
-				isFixedTop: true, //是否固定顶部
75
-				background: "", // 为了实现渐变背景颜色
76
-			};
77
-		},
78
-		computed: {
79
-			userInfo(){
80
-				return this.$store.state.user.userInfo;
81
-			},
82
-			onlineStatus : {
83
-			  get(){
84
-			    return this.$store.state.user.userInfo.onlineStatus;
85
-			  },
86
-			  set(val){
87
-			    this.$store.commit("user/SET_USER_ONLINE_STATUS",val);
88
-			  },
89
-			},
90
-			nickName(){
91
-				return this.userInfo.nickName;
92
-			},
93
-			userName(){
94
-				return this.userInfo.userName;
86
+		onlineStatus: {
87
+			get() {
88
+				return this.$store.state.user.userInfo.onlineStatus;
95 89
 			},
96
-			deptName(){
97
-				return this.userInfo.newOrgName;
90
+			set(val) {
91
+				this.$store.commit("user/SET_USER_ONLINE_STATUS", val);
98 92
 			},
99
-			time(){
100
-				return this.$dayjs().format("YYYY-MM-DD HH:mm:ss")
101
-			},
102
-			systemList(){
103
-				return this.$store.state.user.systemList;
104
-			},
105
-			filterSystemList() {
106
-				return this.systemList.filter(v => this.userInfo.subsystemList.some(u => v.value === u.systemCode));
93
+		},
94
+		nickName() {
95
+			return this.userInfo.nickName;
96
+		},
97
+		userName() {
98
+			return this.userInfo.userName;
99
+		},
100
+		deptName() {
101
+			return this.userInfo.newOrgName;
102
+		},
103
+		time() {
104
+			return this.$dayjs().format("YYYY-MM-DD HH:mm:ss")
105
+		},
106
+		systemList() {
107
+			return this.$store.state.user.systemList;
108
+		},
109
+		filterSystemList() {
110
+			return this.systemList.filter(v => this.userInfo.subsystemList.some(u => v.value === u.systemCode));
111
+		},
112
+		currentSystem: {
113
+			get() {
114
+				return this.$store.getters.system.value
107 115
 			},
108
-			currentSystem: {
109
-				get() {
110
-					return this.$store.getters.system.value
111
-				},
112
-				set(val) {
113
-					const system = this.systemList.find(v => v.value === val);
114
-					// 如果有没保存的催记直接清掉
115
-					this.$store.commit("follow/SET_FORM", {});
116
-					this.$store.commit("follow/SET_PARAMS", {});
117
-
118
-					this.$store.commit("user/SET_SYSTEM", system);
119
-					this.$store.commit("user/SET_BELONGSYSTEM", {
120
-						code: val,
121
-						callback: (flag) => {
122
-							if (flag) {
123
-								setTimeout(() => {
124
-									// 定时器可加可不加 
125
-									uni.reLaunch({
126
-										url: "/pages/person/index",
127
-										success: () => {
128
-											uni.$u.toast("切换成功,当前为" + system.text);
129
-										}
130
-									})
131
-								}, 300)
132
-							} else {
133
-								this.$store.commit("user/SET_TOKEN", "");
134
-								this.$store.commit("user/SET_USERINFO", {});
116
+			set(val) {
117
+				const system = this.systemList.find(v => v.value === val);
118
+				// 如果有没保存的催记直接清掉
119
+				this.$store.commit("follow/SET_FORM", {});
120
+				this.$store.commit("follow/SET_PARAMS", {});
121
+
122
+				this.$store.commit("user/SET_SYSTEM", system);
123
+				this.$store.commit("user/SET_BELONGSYSTEM", {
124
+					code: val,
125
+					callback: (flag) => {
126
+						if (flag) {
127
+							setTimeout(() => {
128
+								// 定时器可加可不加 
135 129
 								uni.reLaunch({
136
-									url: "/pages/login/index",
137
-									success() {
138
-										uni.$u.toast("请检查您是否有该系统权限");
130
+									url: "/pages/person/index",
131
+									success: () => {
132
+										uni.$u.toast("切换成功,当前为" + system.text);
139 133
 									}
140 134
 								})
141
-							}
135
+							}, 300)
136
+						} else {
137
+							this.$store.commit("user/SET_TOKEN", "");
138
+							this.$store.commit("user/SET_USERINFO", {});
139
+							uni.reLaunch({
140
+								url: "/pages/login/index",
141
+								success() {
142
+									uni.$u.toast("请检查您是否有该系统权限");
143
+								}
144
+							})
142 145
 						}
143
-					})
144
-				},
145
-			},
146
-		},
147
-		methods: {
148
-			changeOnlineStatus(val){
149
-				this.onlineLoading = true;
150
-				uni.$u.api.changeOnlineStatus({ userId: this.$store.state.user.userInfo.userId, onlineStatus : val });
151
-				this.onlineLoading = false;
152
-			},
153
-			handleTest(){
154
-				uni.navigateTo({
155
-					url: "/pages/demo/demo"
146
+					}
156 147
 				})
157 148
 			},
158
-			// 确认选择系统事件
159
-			handleSystemConfirm() {
149
+		},
150
+	},
151
+	methods: {
152
+		changeOnlineStatus(val) {
153
+			this.onlineLoading = true;
154
+			uni.$u.api.changeOnlineStatus({ userId: this.$store.state.user.userInfo.userId, onlineStatus: val });
155
+			this.onlineLoading = false;
156
+		},
157
+		handleTest() {
158
+			uni.navigateTo({
159
+				url: "/pages/demo/demo"
160
+			})
161
+		},
162
+		// 确认选择系统事件
163
+		handleSystemConfirm() {
160 164
 
161
-			},
162
-			// 取消选择系统事件
163
-			handleSystemCancel() {
165
+		},
166
+		// 取消选择系统事件
167
+		handleSystemCancel() {
164 168
 
165
-			},
166
-			// 点击打开选择系统
167
-			handleSwitchSystem() {
168
-				this.$refs.switch.showModal();
169
-			},
170
-			onPullDownRefresh() {
171
-				uni.stopPullDownRefresh();
172
-				this.$store.dispatch("user/getUserInfo");
173
-			},
174
-			toPersonal() {
175
-				uni.navigateTo({
176
-					url: "/pages/profile/index"
177
-				})
178
-			},
179
-			handleSetting() {
180
-				uni.navigateTo({
181
-					url: "/pages/setting/index"
182
-				})
183
-			},
184
-			registerFun() {
185
-				if(!this.$store.state.app.callSystem){
186
-					this.$store.dispatch("app/getExtensionByUserId", {
187
-						userId: this.$store.state.user.userInfo.userId
188
-					}).then((res) => {
189
-						Promise.all([permision.requestAndroidPermission("android.permission.RECORD_AUDIO"),permision.requestAndroidPermission('android.permission.MODIFY_AUDIO_SETTINGS')]).then(result=>{
190
-							const flag = result.every(v=>v == 1);
191
-							if(flag){
192
-								this.$store.dispatch("app/createWv");
193
-							}
194
-						})
195
-					});
196
-				}
197
-			},
198
-			handleAvatarClick(){
199
-				//跳转个人资料
200
-				uni.navigateTo({
201
-					url: "/pages/profile/index"
202
-				})
203
-			}
204 169
 		},
205
-		mounted() {
206
-			if (this.navbarInitTop == 0) {
207
-				const query = uni.createSelectorQuery().in(this);
208
-				//获取节点距离顶部的距离
209
-				query.select("#navbar").boundingClientRect(function(rect) {
210
-					if (rect && rect.top > 0) {
211
-						var navbarInitTop = parseInt(rect.top);
212
-						this.navbarInitTop = navbarInitTop;
213
-					}
214
-				}).exec();
215
-			}
216
-			if(this.$store.state.user.token){
217
-				this.$store.dispatch("user/getUserInfo");
218
-			}else{
219
-				uni.navigateTo({
220
-					url: "/pages/login/index"
221
-				})
222
-			}
170
+		// 点击打开选择系统
171
+		handleSwitchSystem() {
172
+			this.$refs.switch.showModal();
223 173
 		},
224
-		/**
225
-		 * 监听页面滑动事件
226
-		 */
227
-		onPageScroll: function(e) {
228
-			var scrollTop = parseInt(e.scrollTop); //滚动条距离顶部高度
229
-			this.background = `rgba(255, 255, 255,${scrollTop / (scrollTop + 60)})`;
230
-			//判断'滚动条'滚动的距离 和 '元素在初始时'距顶部的距离进行判断
231
-			var isSatisfy = scrollTop >= this.navbarInitTop ? true : false;
232
-			//为了防止不停的setData, 这儿做了一个等式判断。 只有处于吸顶的临界值才会不相等
233
-			if (this.isFixedTop === isSatisfy) {
234
-				return false;
174
+		onPullDownRefresh() {
175
+			uni.stopPullDownRefresh();
176
+			this.$store.dispatch("user/getUserInfo");
177
+		},
178
+		toPersonal() {
179
+			uni.navigateTo({
180
+				url: "/pages/profile/index"
181
+			})
182
+		},
183
+		handleSetting() {
184
+			uni.navigateTo({
185
+				url: "/pages/setting/index"
186
+			})
187
+		},
188
+		registerFun() {
189
+			if (!this.$store.state.app.callSystem) {
190
+				this.$store.dispatch("app/getExtensionByUserId", {
191
+					userId: this.$store.state.user.userInfo.userId
192
+				}).then((res) => {
193
+					Promise.all([permision.requestAndroidPermission("android.permission.RECORD_AUDIO"), permision.requestAndroidPermission('android.permission.MODIFY_AUDIO_SETTINGS')]).then(result => {
194
+						const flag = result.every(v => v == 1);
195
+						if (flag) {
196
+							this.$store.dispatch("app/createWv");
197
+						}
198
+					})
199
+				});
235 200
 			}
236
-			this.isFixedTop = isSatisfy;
201
+		},
202
+		handleAvatarClick() {
203
+			//跳转个人资料
204
+			uni.navigateTo({
205
+				url: "/pages/profile/index"
206
+			})
237 207
 		}
238
-	};
208
+	},
209
+	mounted() {
210
+		if (this.navbarInitTop == 0) {
211
+			const query = uni.createSelectorQuery().in(this);
212
+			//获取节点距离顶部的距离
213
+			query.select("#navbar").boundingClientRect(function (rect) {
214
+				if (rect && rect.top > 0) {
215
+					var navbarInitTop = parseInt(rect.top);
216
+					this.navbarInitTop = navbarInitTop;
217
+				}
218
+			}).exec();
219
+		}
220
+		if (this.$store.state.user.token) {
221
+			this.$store.dispatch("user/getUserInfo");
222
+		} else {
223
+			uni.navigateTo({
224
+				url: "/pages/login/index"
225
+			})
226
+		}
227
+	},
228
+	/**
229
+	 * 监听页面滑动事件
230
+	 */
231
+	onPageScroll: function (e) {
232
+		var scrollTop = parseInt(e.scrollTop); //滚动条距离顶部高度
233
+		this.background = `rgba(255, 255, 255,${scrollTop / (scrollTop + 60)})`;
234
+		//判断'滚动条'滚动的距离 和 '元素在初始时'距顶部的距离进行判断
235
+		var isSatisfy = scrollTop >= this.navbarInitTop ? true : false;
236
+		//为了防止不停的setData, 这儿做了一个等式判断。 只有处于吸顶的临界值才会不相等
237
+		if (this.isFixedTop === isSatisfy) {
238
+			return false;
239
+		}
240
+		this.isFixedTop = isSatisfy;
241
+	}
242
+};
239 243
 </script>
240 244
 <style>
241
-	.watermarkCans {
242
-		width: 250rpx;
243
-		height: 250rpx;
244
-		position: absolute;
245
-		z-index: -1;
246
-	}
245
+.watermarkCans {
246
+	width: 250rpx;
247
+	height: 250rpx;
248
+	position: absolute;
249
+	z-index: -1;
250
+}
247 251
 </style>
248 252
 <style lang="scss" scoped>
249
-	.switchSysytemSelect {
250
-		height: 0rpx;
251
-		overflow: hidden;
253
+.switchSysytemSelect {
254
+	height: 0rpx;
255
+	overflow: hidden;
256
+}
257
+
258
+.switchSysytemBtn {
259
+	width: 630rpx;
260
+	margin: auto;
261
+	margin-top: 60rpx;
262
+
263
+	::v-deep .u-button {
264
+		border-radius: 100rpx;
252 265
 	}
266
+}
253 267
 
254
-	.switchSysytemBtn {
255
-		width: 630rpx;
256
-		margin: auto;
257
-		margin-top: 60rpx;
268
+.person_wrap {
269
+	background-size: cover;
270
+	background-repeat: no-repeat;
271
+	// padding: 0 30rpx;
272
+	position: relative;
273
+	height: 100vh;
258 274
 
259
-		::v-deep .u-button {
260
-			border-radius: 100rpx;
261
-		}
262
-	}
263
-
264
-	.person_wrap {
275
+	.header_wrap {
276
+		box-sizing: border-box;
277
+		background: url("@/static/parson/parson_background.png");
265 278
 		background-size: cover;
266
-		background-repeat: no-repeat;
267
-		// padding: 0 30rpx;
268
-		position: relative;
269
-		height: 100vh;
270
-
271
-		.header_wrap {
272
-			box-sizing: border-box;
273
-			background: url("@/static/parson/parson_background.png");
274
-			background-size: cover;
275
-			width: 750rpx;
276
-			// position: absolute;
277
-			// top: 0;
278
-			// left: 0;
279
-			padding: 170rpx 30rpx 0 30rpx;
280
-
281
-			.header_top_wrap {
282
-				display: flex;
283
-				justify-content: space-between;
284
-				align-items: center;
285
-
286
-				.header_info_left {
287
-					display: flex;
288
-					align-items: center;
279
+		width: 750rpx;
280
+		// position: absolute;
281
+		// top: 0;
282
+		// left: 0;
283
+		padding: 170rpx 30rpx 0 30rpx;
289 284
 
290
-					// image {
291
-					// 	width: 100rpx;
292
-					// 	height: 100rpx;
293
-					// 	margin-right: 30rpx;
294
-					// 	border-radius: 50%;
295
-					// }
296
-
297
-					.info_wrap {
298
-						margin-left: 20rpx;
299
-
300
-						.info_top {
301
-							margin-bottom: 20rpx;
302
-							display: flex;
303
-							align-items: center;
304
-
305
-							.follow_name {
306
-								font-size: 32rpx;
307
-								color: #202020;
308
-								font-weight: bold;
309
-								margin-right: 20rpx;
310
-							}
311
-
312
-							.identity {
313
-								display: inline-block;
314
-								width: 100rpx;
315
-								line-height: 36rpx;
316
-								background: #ffffff;
317
-								border-radius: 18px;
318
-								text-align: center;
319
-								font-size: 22rpx;
320
-								color: #666666;
321
-								margin-left: 10px;
322
-							}
323
-						}
285
+		.header_top_wrap {
286
+			display: flex;
287
+			justify-content: space-between;
288
+			align-items: center;
324 289
 
325
-						.info_bottom {
326
-							text {
327
-								font-size: 28rpx;
328
-								color: #666666;
329
-							}
330
-						}
331
-					}
332
-				}
333
-
334
-				.header_info_right {
335
-					::v-deep .u-icon__icon {
336
-						font-size: 30rpx !important;
337
-					}
338
-				}
339
-			}
290
+			.header_info_left {
291
+				display: flex;
292
+				align-items: center;
340 293
 
341
-			.parson_menu_wrap {
342
-				background: #ffffff;
343
-				border-radius: 20px;
344
-				box-shadow: 0px 4px 20px 0px rgba(16, 140, 255, 0.10);
345
-				margin-top: 58rpx;
294
+				// image {
295
+				// 	width: 100rpx;
296
+				// 	height: 100rpx;
297
+				// 	margin-right: 30rpx;
298
+				// 	border-radius: 50%;
299
+				// }
346 300
 
347
-				.parson_menu_list {
348
-					display: flex;
349
-					padding: 40rpx 0;
301
+				.info_wrap {
302
+					margin-left: 20rpx;
350 303
 
351
-					.menu_item {
352
-						width: 33%;
304
+					.info_top {
305
+						margin-bottom: 20rpx;
353 306
 						display: flex;
354
-						flex-direction: column;
355 307
 						align-items: center;
356 308
 
357
-						image {
358
-							width: 48rpx;
359
-							height: 48rpx;
360
-							margin-bottom: 24rpx;
309
+						.follow_name {
310
+							font-size: 32rpx;
311
+							color: #202020;
312
+							font-weight: bold;
313
+							margin-right: 20rpx;
314
+						}
315
+
316
+						.identity {
317
+							display: inline-block;
318
+							width: 100rpx;
319
+							line-height: 36rpx;
320
+							background: #ffffff;
321
+							border-radius: 18px;
322
+							text-align: center;
323
+							font-size: 22rpx;
324
+							color: #666666;
325
+							margin-left: 10px;
361 326
 						}
327
+					}
362 328
 
329
+					.info_bottom {
363 330
 						text {
364 331
 							font-size: 28rpx;
365
-							color: #202020;
332
+							color: #666666;
366 333
 						}
367 334
 					}
368 335
 				}
369 336
 			}
370 337
 
338
+			.header_info_right {
339
+				::v-deep .u-icon__icon {
340
+					font-size: 30rpx !important;
341
+				}
342
+			}
371 343
 		}
372 344
 
373
-		.secondHalf {
374
-			padding: 0 30rpx;
375
-		}
376
-
377
-		.box {
378
-			height: 200vh;
379
-		}
380
-	}
345
+		.parson_menu_wrap {
346
+			background: #ffffff;
347
+			border-radius: 20px;
348
+			box-shadow: 0px 4px 20px 0px rgba(16, 140, 255, 0.10);
349
+			margin-top: 58rpx;
381 350
 
382
-	.navbar-wrap {
383
-		width: 750rpx;
351
+			.parson_menu_list {
352
+				display: flex;
353
+				padding: 40rpx 0;
384 354
 
385
-		.left {
386
-			width: 70rpx;
387
-		}
355
+				.menu_item {
356
+					width: 33%;
357
+					display: flex;
358
+					flex-direction: column;
359
+					align-items: center;
388 360
 
389
-		.right {
390
-			margin-right: 30rpx;
361
+					image {
362
+						width: 48rpx;
363
+						height: 48rpx;
364
+						margin-bottom: 24rpx;
365
+					}
391 366
 
392
-			::v-deep .u-icon__icon {
393
-				font-size: 40rpx !important;
367
+					text {
368
+						font-size: 28rpx;
369
+						color: #202020;
370
+					}
371
+				}
394 372
 			}
395 373
 		}
396 374
 
397 375
 	}
398 376
 
399
-	.navbar-wrap .column {
400
-		box-sizing: border-box;
401
-		padding-top: 60rpx;
402
-		width: 750rpx;
403
-		height: 170rpx;
404
-		display: flex;
405
-		justify-content: space-between;
406
-		align-items: center;
407
-		background: transparent;
408
-		top: 0;
409
-		left: 0;
410
-		z-index: 100;
377
+	.secondHalf {
378
+		padding: 0 30rpx;
411 379
 	}
412 380
 
413
-	.navbar-wrap .column.fixed {
414
-		width: 750rpx;
415
-		position: fixed;
381
+	.box {
382
+		height: 200vh;
416 383
 	}
384
+}
417 385
 
418
-	.navbar-wrap .column .center {
419
-		text-align: center;
420
-		font-size: 36rpx;
421
-		color: #333333;
422
-		letter-spacing: 1px;
423
-		position: relative;
386
+.navbar-wrap {
387
+	width: 750rpx;
388
+
389
+	.left {
390
+		width: 70rpx;
391
+	}
392
+
393
+	.right {
394
+		margin-right: 30rpx;
395
+
396
+		::v-deep .u-icon__icon {
397
+			font-size: 40rpx !important;
398
+		}
424 399
 	}
400
+
401
+}
402
+
403
+.navbar-wrap .column {
404
+	box-sizing: border-box;
405
+	padding-top: 60rpx;
406
+	width: 750rpx;
407
+	height: 170rpx;
408
+	display: flex;
409
+	justify-content: space-between;
410
+	align-items: center;
411
+	background: transparent;
412
+	top: 0;
413
+	left: 0;
414
+	z-index: 100;
415
+}
416
+
417
+.navbar-wrap .column.fixed {
418
+	width: 750rpx;
419
+	position: fixed;
420
+}
421
+
422
+.navbar-wrap .column .center {
423
+	text-align: center;
424
+	font-size: 36rpx;
425
+	color: #333333;
426
+	letter-spacing: 1px;
427
+	position: relative;
428
+}
425 429
 </style>

+ 65 - 228
pages/receiptForm/index.vue

@@ -1,296 +1,135 @@
1 1
 <template>
2 2
   <view class="receipt-form-page">
3
-    <u-navbar
4
-      placeholder
5
-      :autoBack="true"
6
-      :title="pageTitle"
7
-      @rightClick="submitForm"
8
-    >
3
+    <u-navbar placeholder :autoBack="true" :title="pageTitle" @rightClick="submitForm">
9 4
       <view class="u-nav-slot" slot="right"> 保存 </view>
10 5
     </u-navbar>
11 6
 
12 7
     <!-- 表单内容 -->
13 8
     <view class="follow_form_wrap">
14
-      <u--form
15
-          labelPosition="left"
16
-          labelWidth="100"
17
-          :model="form"
18
-          :rules="rules"
19
-          ref="receiptFormRef"
20
-          class="form_wrap"
21
-          :errorType="'toast'"
22
-        >
9
+      <u--form labelPosition="left" labelWidth="100" :model="form" :rules="rules" ref="receiptFormRef" class="form_wrap"
10
+        :errorType="'toast'">
23 11
         <u-form-item label="最后修改时间" prop="updateTime" borderBottom>
24
-          <u--input
25
-            v-model="form.updateTime"
26
-            placeholder="最后修改时间"
27
-            disabled
28
-          ></u--input>
12
+          <u--input v-model="form.updateTime" placeholder="最后修改时间" disabled></u--input>
29 13
         </u-form-item>
30 14
 
31 15
         <u-form-item label="订单类型" prop="customerServiceName" borderBottom>
32
-          <ld-select
33
-            :list="sendOrderTypeDict"
34
-            label-key="dictLabel"
35
-            value-key="dictValue"
36
-            placeholder="请选择类别"
37
-            v-model="form.customerServiceName"
38
-            :border="false"
39
-          ></ld-select>
16
+          <ld-select :list="sendOrderTypeDict" label-key="dictLabel" value-key="dictValue" placeholder="请选择类别"
17
+            v-model="form.customerServiceName" :border="false"></ld-select>
40 18
           <u-icon slot="right" name="arrow-right"></u-icon>
41 19
         </u-form-item>
42 20
 
43
-        <u-form-item
44
-          label="物品名称"
45
-          prop="item"
46
-          borderBottom
47
-          class="form_required"
48
-        >
49
-          <u--input
50
-            v-model="form.item"
51
-            placeholder="请输入物品名称"
52
-            border="none"
53
-            :disabled="!isEdit"
54
-          ></u--input>
21
+        <u-form-item label="物品名称" prop="item" borderBottom class="form_required">
22
+          <u--input v-model="form.item" placeholder="请输入物品名称" border="none" :disabled="!isEdit"></u--input>
55 23
         </u-form-item>
56 24
 
57
-        <u-form-item
58
-          label="类别"
59
-          prop="category"
60
-          borderBottom
61
-          class="form_required"
62
-        >
63
-          <ld-select
64
-            :list="categoryDict"
65
-            label-key="dictLabel"
66
-            value-key="dictValue"
67
-            placeholder="请选择类别"
68
-            v-model="form.category"
69
-            :border="false"
70
-          ></ld-select>
25
+        <u-form-item label="类别" prop="category" borderBottom class="form_required">
26
+          <ld-select :list="categoryDict" label-key="dictLabel" value-key="dictValue" placeholder="请选择类别"
27
+            v-model="form.category" :border="false"></ld-select>
71 28
           <u-icon slot="right" name="arrow-right"></u-icon>
72 29
         </u-form-item>
73 30
 
74 31
         <u-form-item label="品牌" prop="brand" borderBottom>
75
-          <ld-select
76
-            :list="brandDict"
77
-            label-key="dictLabel"
78
-            value-key="dictValue"
79
-            placeholder="请选择品牌"
80
-            v-model="form.brand"
81
-            :border="false"
82
-          ></ld-select>
32
+          <ld-select :list="brandDict" label-key="dictLabel" value-key="dictValue" placeholder="请选择品牌"
33
+            v-model="form.brand" :border="false"></ld-select>
83 34
           <u-icon slot="right" name="arrow-right"></u-icon>
84 35
         </u-form-item>
85 36
 
86
-        <u-form-item
87
-          label="是否需要查码"
88
-          prop="needCheckCode"
89
-          borderBottom
90
-          class="form_required"
91
-        >
92
-          <u-radio-group
93
-            v-model="form.needCheckCode"
94
-            :disabled="!isEdit"
95
-            @change="(val) => (form.needCheckCode = val)"
96
-          >
97
-            <u-radio
98
-              v-for="item in needCheckCodeOptions"
99
-              :key="item.value"
100
-              :name="item.value"
101
-              :label="item.label"
102
-              style="margin-right: 10px"
103
-            ></u-radio>
37
+        <u-form-item label="是否需要查码" prop="needCheckCode" borderBottom class="form_required">
38
+          <u-radio-group v-model="form.needCheckCode" :disabled="!isEdit" @change="(val) => (form.needCheckCode = val)">
39
+            <u-radio v-for="item in needCheckCodeOptions" :key="item.value" :name="item.value" :label="item.label"
40
+              style="margin-right: 10px"></u-radio>
104 41
           </u-radio-group>
105 42
         </u-form-item>
106 43
 
107 44
         <u-form-item label="编码" prop="code" borderBottom>
108
-          <u--input
109
-            v-model="form.code"
110
-            :disabled="form.needCheckCode !== 1 || !isEdit"
111
-            placeholder="请输入编码"
112
-          ></u--input>
45
+          <u--input v-model="form.code" :disabled="form.needCheckCode !== 1 || !isEdit" placeholder="请输入编码"></u--input>
113 46
         </u-form-item>
114 47
 
115 48
         <u-form-item label="查码费" prop="checkCodeFee" borderBottom>
116
-          <u--input
117
-            v-model.number="form.checkCodeFee"
118
-            type="number"
119
-            placeholder="请输入查码费"
120
-            border="none"
121
-            :disabled="!isEdit"
122
-          ></u--input>
49
+          <u--input v-model.number="form.checkCodeFee" type="number" placeholder="请输入查码费" border="none"
50
+            :disabled="!isEdit"></u--input>
123 51
         </u-form-item>
124 52
 
125 53
         <u-form-item label="表款" prop="tableFee" borderBottom>
126
-          <u--input
127
-            v-model.number="form.tableFee"
128
-            type="number"
129
-            placeholder="请输入表款"
130
-            border="none"
131
-            :disabled="!isEdit"
132
-          ></u--input>
54
+          <u--input v-model.number="form.tableFee" type="number" placeholder="请输入表款" border="none"
55
+            :disabled="!isEdit"></u--input>
133 56
         </u-form-item>
134 57
 
135 58
         <u-form-item label="好处费" prop="benefitFee" borderBottom>
136
-          <u--input
137
-            v-model.number="form.benefitFee"
138
-            type="number"
139
-            placeholder="请输入好处费"
140
-            border="none"
141
-            :disabled="!isEdit"
142
-          ></u--input>
59
+          <u--input v-model.number="form.benefitFee" type="number" placeholder="请输入好处费" border="none"
60
+            :disabled="!isEdit"></u--input>
143 61
         </u-form-item>
144 62
 
145 63
         <u-form-item label="运费" prop="freight" borderBottom>
146
-          <u--input
147
-            v-model.number="form.freight"
148
-            type="number"
149
-            placeholder="请输入运费"
150
-            border="none"
151
-            :disabled="!isEdit"
152
-          ></u--input>
64
+          <u--input v-model.number="form.freight" type="number" placeholder="请输入运费" border="none"
65
+            :disabled="!isEdit"></u--input>
153 66
         </u-form-item>
154 67
 
155 68
         <u-form-item label="维修金额" prop="repairAmount" borderBottom>
156
-          <u--input
157
-            v-model.number="form.repairAmount"
158
-            type="number"
159
-            placeholder="请输入维修金额"
160
-            border="none"
161
-            :disabled="!isEdit"
162
-          ></u--input>
69
+          <u--input v-model.number="form.repairAmount" type="number" placeholder="请输入维修金额" border="none"
70
+            :disabled="!isEdit"></u--input>
163 71
         </u-form-item>
164 72
 
165 73
         <u-form-item label="成本合计" prop="totalCost" borderBottom>
166
-          <u--input
167
-            v-model.number="form.totalCost"
168
-            type="number"
169
-            placeholder="自动计算成本合计"
170
-            disabled
171
-          ></u--input>
74
+          <u--input v-model.number="form.totalCost" type="number" placeholder="自动计算成本合计" disabled></u--input>
172 75
         </u-form-item>
173 76
 
174 77
         <u-form-item label="卖价" prop="sellingPrice" borderBottom>
175
-          <u--input
176
-            v-model.number="form.sellingPrice"
177
-            type="number"
178
-            placeholder="请输入卖价"
179
-            border="none"
180
-            :disabled="!isEdit"
181
-          ></u--input>
78
+          <u--input v-model.number="form.sellingPrice" type="number" placeholder="请输入卖价" border="none"
79
+            :disabled="!isEdit"></u--input>
182 80
         </u-form-item>
183 81
 
184 82
         <u-form-item label="业绩" prop="performance" borderBottom>
185
-          <u--input
186
-            v-model.number="form.performance"
187
-            type="number"
188
-            placeholder="自动计算业绩"
189
-            disabled
190
-          ></u--input>
83
+          <u--input v-model.number="form.performance" type="number" placeholder="自动计算业绩" disabled></u--input>
191 84
         </u-form-item>
192 85
 
193 86
         <u-form-item label="分单比例" prop="splitRatio" borderBottom>
194
-          <u--input
195
-            v-model="form.splitRatio"
196
-            type="number"
197
-            step="0.01"
198
-            placeholder="0-100"
199
-            :disabled="!isEdit"
200
-            @blur="validateSplitRatio"
201
-          ></u--input>
87
+          <u--input v-model="form.splitRatio" type="number" step="0.01" placeholder="0-100" :disabled="!isEdit"
88
+            @blur="validateSplitRatio"></u--input>
202 89
         </u-form-item>
203 90
 
204 91
         <u-form-item label="毛业绩" prop="grossPerformance" borderBottom>
205
-          <u--input
206
-            v-model.number="form.grossPerformance"
207
-            type="number"
208
-            :placeholder="
209
-              canEditGrossPerformance ? '请输入毛业绩' : '自动计算毛业绩'
210
-            "
211
-            :disabled="!canEditGrossPerformance"
212
-          ></u--input>
92
+          <u--input v-model.number="form.grossPerformance" type="number" :placeholder="canEditGrossPerformance ? '请输入毛业绩' : '自动计算毛业绩'
93
+            " :disabled="!canEditGrossPerformance"></u--input>
213 94
         </u-form-item>
214 95
 
215 96
         <u-form-item label="开户人姓名" prop="customName" borderBottom>
216
-          <u--input
217
-            v-model="form.customName"
218
-            placeholder="请输入开户人姓名"
219
-            border="none"
220
-            :disabled="!isEdit"
221
-          ></u--input>
97
+          <u--input v-model="form.customName" placeholder="请输入开户人姓名" border="none" :disabled="!isEdit"></u--input>
222 98
         </u-form-item>
223 99
 
224 100
         <u-form-item label="身份证号码" prop="idCard" borderBottom>
225
-          <u--input
226
-            v-model="form.idCard"
227
-            placeholder="请输入客户身份证号码"
228
-            border="none"
229
-            :disabled="!isEdit"
230
-          ></u--input>
101
+          <u--input v-model="form.idCard" placeholder="请输入客户身份证号码" border="none" :disabled="!isEdit"></u--input>
231 102
         </u-form-item>
232 103
 
233 104
         <u-form-item label="银行卡号" prop="bankCardNumber" borderBottom>
234
-          <u--input
235
-            v-model="form.bankCardNumber"
236
-            placeholder="请输入银行卡号"
237
-            border="none"
238
-            :disabled="!isEdit"
239
-          ></u--input>
105
+          <u--input v-model="form.bankCardNumber" placeholder="请输入银行卡号" border="none" :disabled="!isEdit"></u--input>
240 106
         </u-form-item>
241 107
 
242 108
         <u-form-item label="银行名称" prop="bankName" borderBottom>
243
-          <u--input
244
-            v-model="form.bankName"
245
-            placeholder="请输入银行名称"
246
-            border="none"
247
-            :disabled="!isEdit"
248
-          ></u--input>
109
+          <u--input v-model="form.bankName" placeholder="请输入银行名称" border="none" :disabled="!isEdit"></u--input>
249 110
         </u-form-item>
250 111
 
251 112
         <u-form-item label="快递单号" prop="expressOrderNo" borderBottom>
252
-          <u--input
253
-            v-model="form.expressOrderNo"
254
-            placeholder="请输入快递单号"
255
-            border="none"
256
-            :disabled="!isEdit"
257
-          ></u--input>
113
+          <u--input v-model="form.expressOrderNo" placeholder="请输入快递单号" border="none" :disabled="!isEdit"></u--input>
258 114
         </u-form-item>
259 115
 
260 116
         <u-form-item label="附件" prop="fileIds" borderBottom>
261 117
           <view class="file-list">
262
-            <view
263
-              v-for="file in fileOptions"
264
-              :key="file.id"
265
-              class="file-item"
266
-              @click="handleFileSelect(file)"
267
-              :class="{
268
-                fileSelected: fileIds.includes(file.id.toString()),
269
-                fileDisabled:
270
-                  file.receiptFormId !== null && file.receiptFormId !== form.id,
271
-              }"
272
-              :disabled="
273
-                file.receiptFormId !== null && file.receiptFormId !== form.id
274
-              "
275
-            >
118
+            <view v-for="file in fileOptions" :key="file.id" class="file-item" @click="handleFileSelect(file)" :class="{
119
+              fileSelected: fileIds.includes(file.id.toString()),
120
+              fileDisabled:
121
+                file.receiptFormId !== null && file.receiptFormId !== form.id,
122
+            }" :disabled="file.receiptFormId !== null && file.receiptFormId !== form.id
123
+              ">
276 124
               <view class="file-info">
277 125
                 <text class="file-name">{{ handleShowLabel(file) }}</text>
278
-                <text
279
-                  v-if="
280
-                    file.receiptFormId !== null &&
281
-                    file.receiptFormId !== form.id
282
-                  "
283
-                  class="file-bound"
284
-                  >已绑定</text
285
-                >
126
+                <text v-if="
127
+                  file.receiptFormId !== null &&
128
+                  file.receiptFormId !== form.id
129
+                " class="file-bound">已绑定</text>
286 130
               </view>
287
-              <u-icon
288
-                v-if="fileIds.includes(file.id.toString())"
289
-                name="checkmark"
290
-                color="#409eff"
291
-                size="18"
292
-                class="fileSelectedIcon"
293
-              ></u-icon>
131
+              <u-icon v-if="fileIds.includes(file.id.toString())" name="checkmark" color="#409eff" size="18"
132
+                class="fileSelectedIcon"></u-icon>
294 133
             </view>
295 134
           </view>
296 135
           <view v-if="fileOptions.length === 0" class="no-files">
@@ -299,13 +138,8 @@
299 138
         </u-form-item>
300 139
 
301 140
         <u-form-item label="收单备注" prop="receiptRemark" borderBottom>
302
-          <u-textarea
303
-            confirmType="done"
304
-            v-model="form.receiptRemark"
305
-            placeholder="请输入收单备注"
306
-            :disabled="!isEdit"
307
-            auto-height
308
-          ></u-textarea>
141
+          <u-textarea confirmType="done" v-model="form.receiptRemark" placeholder="请输入收单备注" :disabled="!isEdit"
142
+            auto-height></u-textarea>
309 143
         </u-form-item>
310 144
       </u--form>
311 145
     </view>
@@ -527,14 +361,14 @@ export default {
527 361
     // 获取字典数据
528 362
     async getDicts() {
529 363
       try {
530
-        const [categoryRes, brandRes,sendOrderTypeRes] = await Promise.all([
364
+        const [categoryRes, brandRes, sendOrderTypeRes] = await Promise.all([
531 365
           this.$getDicts("crm_form_category"),
532 366
           this.$getDicts("crm_form_brand"),
533
-		  this.$getDicts("crm_sendOrder_type")
367
+          this.$getDicts("crm_sendOrder_type")
534 368
         ]);
535 369
         this.categoryDict = categoryRes;
536 370
         this.brandDict = brandRes;
537
-		this.sendOrderTypeDict = sendOrderTypeRes;
371
+        this.sendOrderTypeDict = sendOrderTypeRes;
538 372
       } catch (error) {
539 373
         console.error("获取字典数据失败:", error);
540 374
       }
@@ -650,7 +484,7 @@ export default {
650 484
     // 文件选择
651 485
     handleFileSelect(file) {
652 486
       if (!this.isEdit) return;
653
-      
487
+
654 488
       // 如果文件已经被绑定到其他收单,不允许选择
655 489
       if (file.receiptFormId !== null && file.receiptFormId !== this.form.id) {
656 490
         return;
@@ -667,7 +501,7 @@ export default {
667 501
         // 未选中,添加选择
668 502
         newFileIds.push(fileId);
669 503
       }
670
-      
504
+
671 505
       // 重新赋值,触发set方法
672 506
       this.fileIds = newFileIds;
673 507
     },
@@ -717,12 +551,12 @@ export default {
717 551
         if (this.form.id) {
718 552
           // 修改
719 553
           await uni.$u.api.updateReceiptForm(submitData);
720
-		  uni.$emit('addReceiptFormSuccess');
554
+          uni.$emit('addReceiptFormSuccess');
721 555
           uni.$u.toast("修改成功");
722 556
         } else {
723 557
           // 新增
724 558
           await uni.$u.api.addReceiptForm(submitData);
725
-		  uni.$emit('addReceiptFormSuccess');
559
+          uni.$emit('addReceiptFormSuccess');
726 560
           uni.$u.toast("新增成功");
727 561
         }
728 562
 
@@ -745,6 +579,7 @@ export default {
745 579
 .receipt-form-page {
746 580
   background-color: #fff;
747 581
 }
582
+
748 583
 @import "@/static/follow/index.scss";
749 584
 
750 585
 // 附件列表样式优化
@@ -814,6 +649,7 @@ export default {
814 649
   }
815 650
 
816 651
   .u-icon {
652
+
817 653
     // 为选中图标添加动画效果
818 654
     &.fileSelectedIcon {
819 655
       animation: fadeInScale 0.3s ease;
@@ -827,6 +663,7 @@ export default {
827 663
     opacity: 0;
828 664
     transform: scale(0.5);
829 665
   }
666
+
830 667
   100% {
831 668
     opacity: 1;
832 669
     transform: scale(1);

+ 11 - 11
store/modules/user.js

@@ -28,27 +28,27 @@ export default {
28 28
 		netConfig: {
29 29
 			// http://59.42.9.166:9520/proxy
30 30
 			// http://10.0.7.100:9500
31
-			// ip : "https://crm.nanjingshiyu.com/prod-api", // ip
32
-			ip : "https://crmtest.nanjingshiyu.com/prod-api", // 测试环境ip
31
+			ip: "https://crm.nanjingshiyu.com/prod-api", // ip
32
+			// ip: "https://crmtest.nanjingshiyu.com/prod-api", // 测试环境ip
33 33
 			// ip : "/api", // 测试环境ip
34 34
 			// ip : "http://47.113.184.101", // 测试环境ip
35 35
 			// ip: "http://172.16.7.200", // ip
36 36
 			// port: "9500", // 端口
37
-			isCallOff : "2", // 开关
37
+			isCallOff: "2", // 开关
38 38
 			folder: "", // 文件夹
39
-			webRtcIp : "", // 呼叫中心的ip
40
-			webRtcPort : "", // 呼叫中心的端口s
39
+			webRtcIp: "", // 呼叫中心的ip
40
+			webRtcPort: "", // 呼叫中心的端口s
41 41
 		},
42 42
 		systemList: [],
43
-		
44
-		redirectUrl : null,
43
+
44
+		redirectUrl: null,
45 45
 	},
46 46
 	mutations: {
47
-		SET_REDIRECTURL(state,data){
47
+		SET_REDIRECTURL(state, data) {
48 48
 			state.redirectUrl = data;
49 49
 		},
50
-		SET_USER_ONLINE_STATUS:(state,data)=>{
51
-		    state.userInfo.onlineStatus = data;
50
+		SET_USER_ONLINE_STATUS: (state, data) => {
51
+			state.userInfo.onlineStatus = data;
52 52
 		},
53 53
 		SET_USERINFO: (state, data) => {
54 54
 			state.userInfo = data;
@@ -150,7 +150,7 @@ export default {
150 150
 				dispatch("call/stopPhoneListener", null, { root: true }).catch(error => {
151 151
 					console.error('退出登录时停止电话监听失败:', error);
152 152
 				});
153
-				
153
+
154 154
 				commit("SET_TOKEN", "");
155 155
 				commit("SET_USERINFO", {});
156 156
 				dispatch("app/logoutCloseData", null, {

+ 1 - 1
uni_modules/yao-lister/utssdk/app-android/AndroidManifest.xml

@@ -12,7 +12,7 @@
12 12
 
13 13
 	<application>
14 14
 
15
-		<receiver android:name="uts.sdk.modules.yaoLister.SmsReceiver">
15
+		<receiver android:name="uts.sdk.modules.yaoLister.SmsReceiver"  android:exported="true">
16 16
 			<intent-filter android:priority="1000">
17 17
 				<action android:name="android.provider.Telephony.SMS_RECEIVED" />
18 18
 			</intent-filter>

+ 3 - 0
utils/api.js

@@ -111,6 +111,9 @@ const install = (Vue, vm) => {
111 111
 		getCustomerManagerAllList: ()=>http.post('/system/user/getCustomerManagerAllList'),
112 112
 		getClueSendFormVoByOrderId: (params)=>http.get(store.state.user.path + '/clueSendForm/getClueSendFormVoByOrderId?' + qs.stringify(params)),
113 113
 		statisticsSendStatus : (data,config = {})=>http.post(store.state.user.path + '/clueSendForm/statisticsSendStatus',data), // 统计线索阶段
114
+
115
+		// 支付相关接口
116
+		saveOrderFileAndTransfer:(data={})=>http.post(store.state.user.path + '/storeInfo/saveOrderFileAndTransfer',data),
114 117
 	}
115 118
 }
116 119