liupeng 2 месяцев назад
Родитель
Сommit
b0746a442d
61 измененных файлов с 5094 добавлено и 8079 удалено
  1. 25 3
      chexnet-master-MP/App.vue
  2. 0 14
      chexnet-master-MP/README.md
  3. 0 20
      chexnet-master-MP/index.html
  4. 5 2
      chexnet-master-MP/main.js
  5. 57 1
      chexnet-master-MP/pages.json
  6. 144 0
      chexnet-master-MP/pages/BMI/BMI.vue
  7. 550 0
      chexnet-master-MP/pages/BMI/BMI_history/BMI_history.vue
  8. 285 0
      chexnet-master-MP/pages/BMI/BMI_output/BMI_output.vue
  9. 642 0
      chexnet-master-MP/pages/ai/ai.vue
  10. 141 0
      chexnet-master-MP/pages/health_tip/health_tip.vue
  11. 116 0
      chexnet-master-MP/pages/health_tip/health_tip_collect/health_tip_collect.vue
  12. 392 0
      chexnet-master-MP/pages/img_process/img_process.vue
  13. 201 0
      chexnet-master-MP/pages/img_process/img_process_history/img_process_history.vue
  14. 158 114
      chexnet-master-MP/pages/index/index.vue
  15. 15 3
      chexnet-master-MP/pages/login/login.vue
  16. 110 0
      chexnet-master-MP/pages/my/family/family.vue
  17. 214 0
      chexnet-master-MP/pages/my/family/family_info/family_info.vue
  18. 14 12
      chexnet-master-MP/pages/my/my.vue
  19. 81 0
      chexnet-master-MP/pages/my/setting/setting.vue
  20. 20 8
      chexnet-master-MP/pages/my/user_info/user_info.vue
  21. 0 184
      chexnet-master-MP/style/animation.css
  22. 0 3721
      chexnet-master-MP/style/base.css
  23. 0 36
      chexnet-master-MP/style/icon.css
  24. 0 3958
      chexnet-master-MP/style/main.css
  25. 0 3
      chexnet-master-MP/style/style.scss
  26. 2 0
      chexnet-master-service/.gitattributes
  27. 33 0
      chexnet-master-service/.gitignore
  28. 1 0
      chexnet-master-service/chexnet-master-img-api.ini
  29. 149 0
      chexnet-master-service/mvnw.cmd
  30. 105 0
      chexnet-master-service/pom.xml
  31. 15 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/ChexnetMasterApplication.java
  32. 121 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/component/MemoryUserRecordSpace.java
  33. 45 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/component/ScheduleTask.java
  34. 143 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/component/XfXhStreamClient.java
  35. 19 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/config/WebConfig.java
  36. 22 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/config/XfXhConfig.java
  37. 123 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/controller/AiController.java
  38. 42 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/controller/ContentCheck.java
  39. 43 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/controller/ImgProcessController.java
  40. 73 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/controller/UserController.java
  41. 7 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/dao/PyDao.java
  42. 73 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/dao/impl/PyDaoA.java
  43. 13 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/dto/InteractMsg.java
  44. 43 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/dto/MsgDTO.java
  45. 122 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/dto/RecordsArray.java
  46. 81 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/dto/RequestDTO.java
  47. 107 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/dto/ResponseDTO.java
  48. 57 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/listener/XfXhWebSocketListener.java
  49. 35 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/mapper/UserMapper.java
  50. 30 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/pojo/Result.java
  51. 24 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/pojo/User.java
  52. 9 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/service/ContentCheckService.java
  53. 8 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/service/ProcessImgService.java
  54. 7 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/service/PyService.java
  55. 17 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/service/UserService.java
  56. 67 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/service/impl/ContentCheckServiceA.java
  57. 50 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/service/impl/ProcessImgServiceB.java
  58. 28 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/service/impl/PyServiceA.java
  59. 123 0
      chexnet-master-service/src/main/java/cn/flea/chexnetmaster/service/impl/UserServiceA.java
  60. 0 0
      chexnet-master-service/src/main/resources/application.yml
  61. 87 0
      chexnet-master-service/src/main/resources/cn/flea/chexnetmaster/mapper/UserMapper.xml

+ 25 - 3
chexnet-master-MP/App.vue

@@ -29,7 +29,7 @@
 		left: 0;
 		right: 0;
 		width: 100vw;
-		margin-bottom: -15vw;
+		margin-bottom:calc(-15vw - 10px);
 	}
 
 	.button-all {
@@ -41,18 +41,40 @@
 		/*box-shadow: 0 10px 20px rgba(0, 0, 0, 0.6); /* 添加阴影效果 */
 	}
 	.button-all:active {
-		opacity: 0.5;
+		opacity: 0.8;
 	    filter: brightness(90%);
 		transform: translateY(2px) translateX(2px);
 	}
+	.button-all::after{
+		display: none;
+	}
 	
 	.no_data{
 		width: 100%; /* 设置宽度 */
 		height: 80vh; /* 设置高度 */
-		background-image: url('@/static/img/no-data.png'); 
+		background-image: url('@/static/img/no-data.png');
 		background-size: 75vw 75vw;
 		background-position: center 10vh;
 		background-repeat: no-repeat; /* 不重复背景图片 */
 	}
+	.divider{
+		width: 100%;
+		height: 1px;
+		background-color: #ccc;
+	}
 	
+	.bottom-button{
+		height: 50px;
+		color: #fff;
+		margin: 0 10px;
+		width: calc(100vw - 60px);
+		position: fixed; 
+		bottom: 30px;
+		border-radius: 50px;
+		background-color: #1678ff;
+	}
+	.bottom-button:active{
+		opacity: 0.7;
+		filter: brightness(80%);
+	}
 </style>

Разница между файлами не показана из-за своего большого размера
+ 0 - 14
chexnet-master-MP/README.md


+ 0 - 20
chexnet-master-MP/index.html

@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="UTF-8" />
-    <script>
-      var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
-        CSS.supports('top: constant(a)'))
-      document.write(
-        '<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
-        (coverSupport ? ', viewport-fit=cover' : '') + '" />')
-    </script>
-    <title></title>
-    <!--preload-links-->
-    <!--app-context-->
-  </head>
-  <body>
-    <div id="app"><!--app-html--></div>
-    <script type="module" src="/main.js"></script>
-  </body>
-</html>

+ 5 - 2
chexnet-master-MP/main.js

@@ -21,8 +21,11 @@ export function createApp() {
 }
 // #endif
 
-import user_api from './data/user_api.js';  
+import user_api from '@/data/user_api.js';  
 Vue.prototype.$user_api = user_api;
 
-import util from './data/util.js';  
+import util from '@/data/util.js';  
 Vue.prototype.$util = util;
+
+import content_check from '@/data/content_check.js'
+Vue.prototype.$content_check = content_check;

+ 57 - 1
chexnet-master-MP/pages.json

@@ -41,6 +41,7 @@
 			"style" : 
 			{
 				"navigationBarTitleText" : "BMI计算",
+				// "enablePullDownRefresh": true,
 				"navigationBarBackgroundColor": "#ffffff",
 				"navigationBarTextStyle": "black"
 			}
@@ -66,6 +67,7 @@
 			"style" : 
 			{
 				"navigationBarTitleText" : "BMI 记录",
+				"enablePullDownRefresh": true,
 				"navigationBarBackgroundColor": "#f1f3f2"
 			}
 		},
@@ -83,7 +85,61 @@
 			"path" : "pages/ai/ai",
 			"style" : 
 			{
-				"navigationBarTitleText" : ""
+				"navigationBarTitleText" : "医伴 AI",
+				"enablePullDownRefresh": true,
+				"navigationBarTextStyle": "black",
+				"navigationBarBackgroundColor": "#d4f4c2"
+			}
+		},
+		{
+			"path" : "pages/my/setting/setting",
+			"style" : 
+			{
+				"navigationBarTitleText" : "设置",
+				"navigationBarBackgroundColor": "#ffffff",
+				"navigationBarTextStyle": "black"
+			}
+		},
+		{
+			"path" : "pages/health_tip/health_tip",
+			"style" : 
+			{
+				"navigationBarTitleText" : "健康小知识"
+			}
+		},
+		{
+			"path" : "pages/health_tip/health_tip_collect/health_tip_collect",
+			"style" : 
+			{
+				"navigationBarTitleText" : "健康知识收藏夹",
+				"navigationBarBackgroundColor": "#f5f5f5"
+			}
+		},
+		{
+			"path" : "pages/my/family/family",
+			"style" : 
+			{
+				"navigationBarTitleText" : "家庭成员",
+				"enablePullDownRefresh": true,
+				"navigationBarTextStyle": "white",
+				"navigationBarBackgroundColor": "#1678ff"
+			}
+		},
+		{
+			"path" : "pages/my/family/family_info/family_info",
+			"style" : 
+			{
+				"navigationBarTitleText" : "成员资料",
+				"navigationBarTextStyle": "white",
+				"navigationBarBackgroundColor": "#1678ff"
+			}
+		},
+		{
+			"path" : "pages/img_process/img_process_history/img_process_history",
+			"style" : 
+			{
+				"navigationBarTitleText" : "病例识别记录",
+				"navigationBarBackgroundColor": "#f6f6f6"
 			}
 		}
 	],

+ 144 - 0
chexnet-master-MP/pages/BMI/BMI.vue

@@ -0,0 +1,144 @@
+<template>
+	<view class="margin-xl">
+		<uv-gap height="10" ></uv-gap>
+		<view class="flex justify-between">
+			<view>
+				<p class="head-text">年龄</p>
+				<uv-gap height="10" ></uv-gap>
+				<view style="width: 50vw">
+					<input type="number" v-model="BMI.age" @input="validateInput('age')" maxlength="3" 
+						class="input-text" placeholder="请输入年龄" 
+						placeholder-style="color: #cccccc; font-size: 24px; font-weight: 100;"
+					/>
+				</view>
+			</view>
+			
+			<view>
+				<p style="text-align: center;" class="head-text">历史</p>
+				<uv-gap height="5"></uv-gap>
+				<image @click="$util.navigateTo('/pages/BMI/BMI_history/BMI_history')" class="image_bmi button-all" src="@/static/img/history_bmi.png"></image>
+			</view>
+		</view>
+		
+		<uv-gap height="20" ></uv-gap>
+		<view class="head-text">
+			<p>身高(厘米)</p>
+		</view>
+		
+		<uv-gap height="10" ></uv-gap>
+		<view>
+			<input type="number" v-model="BMI.height" @input="validateInput('height')" maxlength="3" 
+				class="input-text" placeholder="请输入身高" 
+				placeholder-style="color: #cccccc; font-size: 24px; font-weight: 100;"
+			/>
+		</view>
+		
+		<uv-gap height="20" ></uv-gap>
+		<view class="head-text">
+			<p>体重(公斤)</p>
+		</view>
+		
+		<uv-gap height="10" ></uv-gap>
+		<view>
+			<input type="number" v-model="BMI.weight" @input="validateInput('weight')" maxlength="3" 
+				class="input-text" placeholder="请输入体重" 
+				placeholder-style="color: #cccccc; font-size: 24px; font-weight: 100;"
+			/>
+		</view>
+		
+		<uv-gap height="30" ></uv-gap>
+		<view class="tip-text">
+			<p class="title">BMI指数:</p>
+			<uv-gap height="5" ></uv-gap>
+			<p>简称体质指数,是通过体重公斤除以身高米数平方得出的数字。是目前国际上常用的衡量人体胖瘦程度以及是否健康的一个标准。</p>
+		</view>
+		
+		<uv-button @click="to_BMI_output()" customStyle="position: fixed; bottom: 40px;width: calc(100vw - 50px);" shape="circle" size="large" color="#1678ff">开始计算</uv-button>
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		onLoad() {
+			let user = uni.getStorageSync("user");
+			if(user){
+				this.BMI.age = user.age;
+				this.BMI.gender = user.gender;
+			}
+		},
+		data() {
+			return {
+				BMI: {
+					age: null,
+					gender: 0,
+					height: null,
+					weight: null
+				}
+			}
+		},
+		methods: {
+			to_BMI_output(){
+				if(!this.BMI.age) uni.showToast({duration:1500,icon:'error',title: '请输入年龄 !'});
+				else if(this.BMI.age < 14) uni.showToast({duration:1500,icon:'none',title: '14岁以下不提供此服务!'});
+				else if(!this.BMI.height) uni.showToast({duration:1500,icon:'error',title: '请输入身高 !'});
+				else if(!this.BMI.weight) uni.showToast({duration:1500,icon:'error',title: '请输入体重 !'});
+				else{
+					// 将对象参数转为JSON字符串,并使用encodeURIComponent编码
+					const BMI = encodeURIComponent(JSON.stringify(this.BMI));
+					 
+					// 跳转页面并传递对象参数
+					uni.navigateTo({
+						url: `/pages/BMI/BMI_output/BMI_output?BMI=${BMI}`
+					});
+				}
+			},
+			validateInput(fieldName) {
+				const value = this.BMI[fieldName];
+
+				// 如果输入的是负数或者不是数字,则清空输入框
+				if (value < 0 || isNaN(value)) {
+					this.BMI[fieldName] = null;
+					uni.showToast({duration:1500,icon:'error',title: '请输入正数 !'});
+				}
+			}
+		}
+	}
+</script>
+
+<style>
+	page{
+		background-color: #ffffff;
+	}
+	.head-text{
+		color: #8c92ad;
+		font-size: 14px;
+	}
+	.input-text {
+	    /* 去掉默认边框 */
+	    border: none;
+	    /* 添加底部下划线 */
+	    border-bottom: 1px solid #cccccc; /* 下划线颜色和粗细 */
+	    /* 其他样式 */
+	    width: 100%;
+		height: 7vh;
+	    padding-bottom: 5px;
+	    font-size: 24px;
+		font-weight: 1000;
+		color: #000;
+	    outline: none; /* 移除聚焦时的默认边框 */
+	}
+	.tip-text{
+		color: #666666;
+		font-size: 14px;
+	}
+	.tip-text .title{
+		font-weight: 1000;
+	}
+	
+	.image_bmi{
+		width: 60px;
+		height: 60px;
+	}
+
+</style>

+ 550 - 0
chexnet-master-MP/pages/BMI/BMI_history/BMI_history.vue

@@ -0,0 +1,550 @@
+<template>
+	<view v-if="bmi_history" class="content">
+		<!-- 折线-开始 -->
+		<view class="chart-con gap">
+			<view class="chart-wrap">
+				<view class="title" style="height: 18px;">
+					<view class="ver-line"></view>
+					<view @click="showDropdown = !showDropdown" class="title-desc">
+						<text>平均值 </text>
+						<text class="t-sm">{{type}}<text class="cuIcon-triangledownfill"></text></text>
+						<!-- 下拉选择器 -->
+					</view>
+					<view v-show="showDropdown" class="dropdown-container flex justify-between">
+						<view class="dropdown-item" @click="selectItem('year')">年</view>
+						<view class="dropdown-item" @click="selectItem('month')">月</view>
+						<view class="dropdown-item" @click="selectItem('day')">日</view>
+					  <!-- <view class="dropdown-item" @click="selectItem('hour')">时</view> -->
+					</view>
+				</view>
+				<view class="line-chart-con">
+					<l-echart id="123" class="line-chart" ref="lineChart"></l-echart>
+				</view>
+				<!-- <text class="margin-left t-sm">注:数据只保留一年</text> -->
+			</view>
+		</view>
+		<!-- 折线-结束 -->
+		<view class="chart-con gap">
+			<view class="chart-wrap">
+				<view class="title">
+					<view class="ver-line"></view>
+					<view @click="openDatetimePicker" class="title-desc">
+						<text>详细记录</text>
+						<text class="t-sm">
+							{{selectDate.year}} 年 {{selectDate.month}} 月 <!-- {{selectDate.day}} 日 -->
+							<text class="cuIcon-triangledownfill"></text>
+						</text>
+					</view>
+				</view>
+				
+				<uv-swipe-action v-if="refresh">
+					<uv-swipe-action-item @click="delData($event,key)" v-for="(value, key) in select_history" :key="key" :options="options">
+						<view @longpress="check_delDatag({'index':0},key)" class="swipe-action uv-border-top uv-border-bottom">
+							<view class="swipe-action__content">
+								<view class="margin-left margin-right">
+									<view class="margin-bottom-xs flex justify-between">
+										<view class="flex">
+											<text class="margin-right" style="font-size: 24px;font-weight: 600;">{{value.bmi}}</text>
+											<div style="display: flex;font-weight: 600;align-items: center;justify-content: center;">
+												<span style="color: #57bff6;" v-if="value.bmi < 18.5">偏瘦</span>
+												<span style="color: #13d080;" v-else-if="value.bmi >= 18.5 && value.bmi < 24.0">正常</span>
+												<span style="color: #ffb951;" v-else-if="value.bmi >= 24.0 && value.bmi < 28.0">偏重</span>
+												<span style="color: #ff7433;" v-else-if="value.bmi >= 28.0">肥胖</span>
+											</div>
+										</view>
+										<text style="color:#999;display: flex;align-items: center;justify-content: center;">{{value.time}}</text>
+									</view>
+									<view style="color:#666;" class="flex justify-start">
+										<text class="margin-right">身高:{{value.height}}cm</text>
+										<text>体重:{{value.weight}}kg</text>
+									</view>
+								</view>
+							</view>
+						</view>
+						<!-- <uv-divider v-if="key != lastKey" style="margin:0 ;padding: 0;height: 1px;"></uv-divider> -->
+						<view v-if="key != lastKey" style="background-color: #ccc;bottom: 0;height: 1px;margin:0 10px;"></view>
+					</uv-swipe-action-item>
+				</uv-swipe-action>
+				<view v-else style="height: 3000px;"></view>
+			</view>
+			<uv-datetime-picker :formatter="formatter" :minDate="firstkey" :maxDate="lastKey" ref="datetimePicker" v-model="dateValue" mode="year-month" @confirm="confirm"></uv-datetime-picker>
+		</view>
+	</view>
+	<view v-else class="no_data"></view>
+</template>
+
+<script>
+	import * as echarts from '@/uni_modules/lime-echart/static/echarts.min.js';
+	export default {
+		onPullDownRefresh() {
+			let bmi_history = uni.getStorageSync('bmi_history');
+			this.bmi_history = null;
+			if(bmi_history && Object.keys(bmi_history).length != 0) this.bmi_history = bmi_history;
+			else uni.showToast({duration:1500,icon:"error",title: '暂无数据 !'});
+			this.$forceUpdate();
+			setTimeout(() => {uni.stopPullDownRefresh();}, 1000);
+		},
+		onLoad() {
+			let bmi_history = uni.getStorageSync('bmi_history');
+			if(bmi_history && Object.keys(bmi_history).length != 0) this.bmi_history = bmi_history;
+			else uni.showToast({duration:1500,icon:"error",title: '暂无数据 !'});
+		},
+		mounted() {
+			if(this.bmi_history){
+				this.loadLineData("month");
+			}
+			
+			// 获取对象的所有键
+			const keys = Object.keys(this.bmi_history);
+			// 获取最后一个键
+			const lastKey = keys[keys.length - 1];
+			this.lastKey = lastKey;
+			this.firstkey = keys[0];
+			this.confirm({'value': lastKey});
+		},
+		data() {
+			return {
+				selectDate: {
+					year: null,
+					month: null,
+					day: null
+				},
+				dateValue: Number(new Date()),
+				month: null,
+				bmi_history: null,
+				select_history: null,
+				showDropdown: false,
+				type: null,
+				options: [{
+					text: '删除',
+					style: {
+						backgroundColor: '#f56c6c'
+					}
+				}],
+				firstkey: null,
+				lastKey: null,
+				refresh: true
+			}
+		},
+		methods: {
+			check_delDatag(e,key){
+				uni.showModal({
+					title: '删除此纪录',
+					content: '是否要删除此纪录?',
+					success: (res) => { 
+						if (res.confirm) 
+							this.delData(e,key); 
+					}  
+				})
+			},
+			delData(e,key){
+				console.log('e: ',e);
+				console.log('key: ',key);
+				if(e['index'] === 0){
+					let bmi_history = uni.getStorageSync('bmi_history');
+					if (bmi_history.hasOwnProperty(key)) {
+						delete bmi_history[key];
+						uni.setStorageSync('bmi_history',bmi_history);
+					}
+					if (this.select_history.hasOwnProperty(key)) {
+						delete this.select_history[key];
+					}
+					this.$forceUpdate();
+					this.refresh = false;
+					setTimeout(() => this.refresh = true,1);
+				}
+			},
+			openDatetimePicker() {
+				this.$refs.datetimePicker.open();
+			},
+			confirm(e) {
+				console.log('confirm', e);
+				const date = new Date(parseInt(e.value));
+				this.selectDate.year = date.getFullYear();
+				this.selectDate.month = date.getMonth() + 1;
+				// this.selectDate.day = date.getDate();
+				
+				this.select_history =this.$util.reversedObject(filterByDate(this.selectDate,this.bmi_history));
+				
+				this.$forceUpdate();
+				this.refresh = false;
+				setTimeout(() => this.refresh = true,1);
+				
+				function filterByDate(dateObj, timestampObj) {
+				    const { year, month } = dateObj;
+				    const result = {};
+				
+				    for (const [timestamp, value] of Object.entries(timestampObj)) {
+				        const date = new Date(parseInt(timestamp));
+				        if ((year === null || date.getFullYear() === year) &&
+				            (month === null || date.getMonth() + 1 === month)) {
+				            const day = date.getDate().toString().padStart(2, '0');
+				            const hours = date.getHours().toString().padStart(2, '0');
+				            const minutes = date.getMinutes().toString().padStart(2, '0');
+				            result[timestamp] = { ...value, time: `${day}日 ${hours}时 ${minutes}分` };
+				        }
+				    }
+				    return result;
+				}
+
+			},
+			formatter(type, value) {
+				if (type === 'year') {
+					return `${value}年`
+				}
+				if (type === 'month') {
+					return `${value}月`
+				}
+				if (type === 'day') {
+					return `${value}日`
+				}
+				return value
+			},
+			selectItem(item) {
+				this.showDropdown = false; // 关闭下拉选择器
+				this.loadLineData(item);
+			},
+			loadLineData(type) {
+				let res = this.handle_data(type);
+				
+				let option = {
+					xAxis: {
+						type: 'category',
+						// x轴数据文字颜色
+						axisLabel: {
+							color: '#a7a7a7'
+						},
+						// x轴那天坐标轴线的颜色
+						axisLine: {
+							lineStyle: {
+								color: '#f1f1f1',
+							}
+						},
+						//x轴上面刻度线隐藏
+						axisTick: {
+							show: false,
+						},
+						//这里是x轴数据
+						data: res.xData
+					},
+					//设置网格
+					grid: {
+						top: 40,
+						bottom: 30,
+					},
+					//y轴设置
+					yAxis: {
+						type: 'value',
+						//y轴标签文字颜色
+						axisLabel: {
+							color: '#a7a7a7'
+						},
+						// y轴分割线设置为虚线
+						splitLine: {
+							show: true,
+							lineStyle: {
+								type: 'dashed'
+							}
+						}
+					},
+					//设置提示为点击时
+					tooltip: {
+						trigger: 'axis',
+						triggerOn: 'click',
+						formatter: '{b} \n 数据: {c}'
+					},
+					//设置曲线的颜色
+					color: ['#4e9d77'],
+					series: [{
+						//这里是数据
+						data: res.yData,
+						type: 'line',
+						//设置为平滑,默认为折线
+						smooth: true,
+					}],
+					//设置数据缩放,手指缩放
+					dataZoom:{
+						type:'inside',//inside移动端就是手指缩放,slider
+						id:'123',
+					}
+				};
+			
+				this.$refs.lineChart.init(echarts, chart => {
+					chart.setOption(option);
+				});
+			},
+			handle_data(type = null){
+				
+				let xData;
+				if(type === null) xData = this.formatTimestamps(this.bmi_history);
+				else xData = this.formatTimestamps_typeB(this.bmi_history,type);
+				
+				let yData = this.extractBmis(this.bmi_history);
+				
+				console.log('xData: ',xData);
+				console.log('yData: ',yData);
+				
+				let res = averageData(xData, yData)
+				return {
+					xData: res.newXData, 
+					yData: res.newYData
+				}
+				
+				function averageData(xData, yData) {
+				    // 创建一个Map来存储每个时间点的总和和计数
+				    const dataMap = new Map();
+				
+				    // 遍历xData和yData
+				    for (let i = 0; i < xData.length; i++) {
+				        const time = xData[i];
+				        const value = parseFloat(yData[i]);
+				
+				        if (dataMap.has(time)) {
+				            // 如果时间点已经存在,更新总和和计数
+				            const [sum, count] = dataMap.get(time);
+				            dataMap.set(time, [sum + value, count + 1]);
+				        } else {
+				            // 如果时间点不存在,初始化总和和计数
+				            dataMap.set(time, [value, 1]);
+				        }
+				    }
+				
+				    // 创建新的xData和yData
+				    const newXData = [];
+				    const newYData = [];
+				
+				    // 遍历Map计算平均值
+				    for (const [time, [sum, count]] of dataMap) {
+				        newXData.push(time);
+				        newYData.push((sum / count).toFixed(2)); // 保留两位小数
+				    }
+				
+				    return { newXData, newYData };
+				}
+			},
+			extractBmis(obj) {
+			    const bmis = [];
+			    function traverse(object) {
+			        for (let key in object) {
+			            if (object.hasOwnProperty(key)) {
+			                const value = object[key];
+			                if (typeof value === 'object' && value !== null) {
+			                    if (value.bmi !== undefined) {
+			                        bmis.push(value.bmi);
+			                    }
+			                    traverse(value); // 递归遍历子对象
+			                }
+			            }
+			        }
+			    }
+			
+			    traverse(obj);
+			    return bmis;
+			},
+			formatTimestamps(obj) {
+				
+				return this.formatTimestamps_typeB(obj, getTimeGranularity(obj));
+				
+				function getTimeGranularity(timestamps) {
+				    const dates = Object.keys(timestamps).map(ts => new Date(parseInt(ts)));
+				
+				    const allSameYear = dates.every(date => date.getFullYear() === dates[0].getFullYear());
+				    if (!allSameYear) return 'year';
+				
+				    const allSameMonth = dates.every(date => date.getMonth() === dates[0].getMonth());
+				    if (!allSameMonth) return 'month';
+				
+				    const allSameDay = dates.every(date => date.getDate() === dates[0].getDate());
+				    if (!allSameDay) return 'day';
+				}
+			},
+			formatTimestamps_typeB(obj, type) {
+				
+				if(type === 'year')this.type = '年';
+				if(type === 'month')this.type = '月';
+				if(type === 'day')this.type = '日';
+				if(type === 'hour')this.type = '时';
+				
+			    const timestamps = Object.keys(obj).map(ts => new Date(parseInt(ts)));
+			
+			    return timestamps.map(ts => {
+			        switch (type) {
+			            case 'year':
+			                return ts.getFullYear().toString();
+			            case 'month':
+			                return (ts.getMonth() + 1).toString();
+			            case 'day':
+							return (ts.getMonth() + 1) + '/' + ts.getDate().toString().padStart(2, '0');
+			                // return ts.getDate().toString();
+			            case 'hour':
+			                return ts.getHours() + ':' + ts.getMinutes().toString().padStart(2, '0');
+			            default:
+			                throw new Error('Invalid granularity');
+			        }
+			    });
+			}
+		}
+	}
+</script>
+
+<style>
+	
+	.dropdown-item {
+	  padding: 3px;
+	  color: #5e5e5e;
+	  border-radius: 10px;
+	  cursor: pointer;
+	}
+	
+	.dropdown-item:hover {
+		background-color: #e0e0e0;
+	}
+	
+	.dropdown-container {
+	  padding: 3px;
+	  font-size: 18px;
+	  position: relative;
+	  top: 3px; /* 根据实际需求调整距离 */
+	  background-color: #f3f5f4;
+	  border-radius: 10px;
+	  // box-shadow: 0 2px 10px rgba(0, 0, 0, 0.8);
+	  z-index: 100; /* 确保选择器在其他内容之上 */
+	}
+</style>
+
+<style lang="scss">
+	.uv-page {
+		padding: 0;
+	}
+	.uv-demo-block__title {
+		padding: 10px 0 2px 15px;
+	}
+	.swipe-action {
+		&__content {
+			padding: 25rpx 0;
+			&__text {
+				font-size: 15px;
+				color: #222;
+				padding-left: 30rpx;
+			}
+		}
+	}
+</style>
+
+<style lang="scss" scoped>
+	
+	.content {
+		width: 100%;
+		min-height: 100vh;
+		background-color: #f1f3f2;
+		padding: 20rpx 0rpx 100rpx;
+	}
+	.t-sm{
+		font-size: 22rpx;
+		color: #6e6e6e;
+		padding-left: 10rpx;
+	}
+	.chart-con {
+		width: 100%;
+		box-sizing: border-box;
+		padding: 0rpx 28rpx;
+
+		.chart-wrap {
+			width: 100%;
+			box-sizing: border-box;
+			background-color: #ffffff;
+			padding: 32rpx 0rpx;
+			border-radius: 20rpx;
+
+			.title {
+				box-sizing: border-box;
+				width: 100%;
+				padding: 0rpx 28rpx;
+				display: flex;
+				flex-direction: row;
+				justify-content: flex-start;
+				align-items: center;
+			}
+
+			.ver-line {
+				height: 30rpx;
+				width: 8rpx;
+				border-radius: 10rpx;
+				background-color: #4e9d77;
+			}
+
+			.title-desc {
+				font-size: 30rpx;
+				color: #222222;
+				margin-left: 22rpx;
+				font-weight: bold;
+			}
+
+			
+			.line-chart-con {
+				width: 100%;
+				box-sizing: border-box;
+				padding: 0rpx 28rpx;
+
+				.fun-tabs {
+					margin-top: 42rpx;
+					display: flex;
+					flex-direction: row;
+					justify-content: space-between;
+					align-self: center;
+					width: 100%;
+					box-sizing: border-box;
+
+					.tab-item {
+						width: 200rpx;
+						height: 120rpx;
+						border-radius: 10rpx;
+						padding-left: 20rpx;
+						background: #ffffff;
+						border: 1rpx solid #ececec;
+						display: flex;
+						flex-direction: column;
+						justify-content: center;
+						align-items: flex-start;
+						box-sizing: border-box;
+
+						.item-name {
+							color: #6e6e6e;
+							font-size: 20rpx;
+						}
+
+						.item-val {
+							color: #222222;
+							font-size: 24rpx;
+							font-weight: bold;
+							margin-top: 20rpx;
+						}
+					}
+
+					.selected {
+						background: #edf5f1 !important;
+						border: 1rpx solid #4e9d77 !important;
+
+						.item-name {
+							color: #4e9d77 !important;
+						}
+
+						.item-val {
+							color: #4e9d77 !important;
+						}
+					}
+				}
+
+				.line-chart {
+					margin-top: 30rpx;
+					height: 380rpx;
+				}
+			}
+		}
+	}
+	.gap {
+		margin-top: 30rpx;
+	}
+	
+</style>
+

+ 285 - 0
chexnet-master-MP/pages/BMI/BMI_output/BMI_output.vue

@@ -0,0 +1,285 @@
+<template>
+	<view class="margin-xl">
+		
+		<view class="flex justify-between">
+			<view>
+				<p class="BMI">{{bmi}}</p>
+				<uv-gap height="5"></uv-gap>
+				<p class="wight-head">身高体重指数</p>
+			</view>
+			
+			<view>
+				<image @click="$util.navigateTo('/pages/BMI/BMI_history/BMI_history')" class="image_bmi button-all" src="@/static/img/history_bmi.png"></image>
+				<uv-gap height="5"></uv-gap>
+				<p style="text-align: center;" class="wight-head">历史</p>
+			</view>
+			
+		</view>
+		
+		<uv-gap height="40"></uv-gap>
+		
+		<div class="bmi-labels">
+			<span class="weight-tip" :class="{ 'active1 active': bmi < 18.5 }">偏瘦</span>
+			<span class="weight-tip" :class="{ 'active2 active': bmi >= 18.5 && bmi < 24.0 }">正常</span>
+			<span class="weight-tip" :class="{ 'active3 active': bmi >= 24.0 && bmi < 28.0 }">偏重</span>
+			<span class="weight-tip" :class="{ 'active4 active': bmi >= 28.0 }">肥胖</span>
+		</div>
+		
+		<uv-gap height="15"></uv-gap>
+		
+		<div class="bmi-bar"></div>
+		
+		<uv-gap height="15"></uv-gap>
+		
+		<div class="bmi-values">
+			<span></span>
+			<span>18.5</span>
+			<span>24.0</span>
+			<span>28.0</span>
+			<span></span>
+		</div>
+		
+		<uv-gap height="25"></uv-gap>
+		
+		<uv-divider></uv-divider>
+		
+		<uv-gap height="25"></uv-gap>
+		
+		<p class="sug-head">数据分析</p>
+		
+		<uv-gap height="25"></uv-gap>
+		
+		<view class="flex justify-between">
+			<p class="sug-title">身高(厘米)</p>
+			<p class="sug-res">{{height}}cm</p>
+		</view>
+		
+		<uv-gap height="25"></uv-gap>
+		
+		<view class="flex justify-between">
+			<p class="sug-title">建议体重(公斤)</p>
+			<p class="sug-res">{{min_weight}} ~ {{max_weight}}kg</p>
+		</view>
+		
+		<uv-button @click="save()" customStyle="position: fixed; bottom: 40px;width: calc(100vw - 50px);" shape="circle" size="large" color="#1678ff">保存</uv-button>
+	</view>
+</template>
+
+<script>
+	export default {
+		onLoad(options) {
+			// 获取传递的对象参数,使用decodeURIComponent解码,并转为对象
+			if ('BMI' in options) {
+				let BMI = JSON.parse(decodeURIComponent(options.BMI));
+				this.BMI = BMI;
+				let bmi = this.calculateBMI(BMI.age, BMI.gender, BMI.weight, BMI.height);
+				
+				this.bmi = bmi.bmi;
+				this.height = parseFloat(BMI.height).toFixed(1);
+				let sug_weight = this.calculateSuggestedWeightRange(BMI.height);
+				console.log(bmi);
+				console.log(sug_weight);
+				this.min_weight = sug_weight.minWeight;
+				this.max_weight = sug_weight.maxWeight;
+			}
+			else{
+				uni.navigateTo({url: '/pages/BMI/BMI'});
+			}
+		},
+		data() {
+			return {
+				bmi: null,
+				height: null,
+				min_weight: null,
+				max_weight: null,
+				saved: false
+			}
+		},
+		methods: {
+			save(){
+				if(this.saved){
+					uni.showToast({icon:'none',title: '已保存,请勿重复操作',duration:1500});
+					return ;
+				}
+				
+				this.saved = true;
+				
+				let BMI = this.BMI;
+				
+				const timestamp = Date.now();
+				BMI['bmi'] = this.bmi;
+				
+				console.log('BMI: ',BMI);
+				
+				let bmi_history = uni.getStorageSync('bmi_history');
+				if(bmi_history){
+					bmi_history[timestamp.toString()] = BMI;
+					uni.setStorageSync('bmi_history',bmi_history);
+				}
+				else{
+					bmi_history = {};
+					bmi_history[timestamp.toString()] = BMI;
+					uni.setStorageSync('bmi_history',bmi_history);
+				}
+				uni.showToast({icon:'success',title: '保存成功',duration:1500});
+			},
+			calculateBMI(age, gender, weight, height) {
+			    // 将身高从米转换为米,将体重从千克转换为千克
+			    height = height/100;
+				// const bmi = weight / (height * height);
+				const bmi = parseFloat((weight / (height * height)).toFixed(1));
+			   
+				console.log(bmi);
+			    
+				let bmiCategory;
+			    if (bmi < 18.5) {
+			        bmiCategory = "体重过轻";
+			    } else if (bmi >= 18.5 && bmi <= 24) {
+			        bmiCategory = "正常体重";
+			    } else if (bmi > 24 && bmi < 29.9) {
+			        bmiCategory = "超重";
+			    } else {
+			        bmiCategory = "肥胖";
+			    }
+			
+			    let additionalInfo = "";
+			    if (gender === 0) {
+			        additionalInfo = `男性,${age}岁,BMI值为${bmi.toFixed(2)},属于${bmiCategory}。`;
+			    } else if (gender === 1) {
+			        additionalInfo = `女性,${age}岁,BMI值为${bmi.toFixed(2)},属于${bmiCategory}。`;
+			    } else {
+			        additionalInfo = `性别未知,BMI值为${bmi.toFixed(2)},属于${bmiCategory}。`;
+			    }
+			
+			    return {
+			        bmi: bmi.toFixed(1),
+			        category: bmiCategory,
+			        info: additionalInfo
+			    };
+			},
+			calculateSuggestedWeightRange(height) {
+				height = height/100;
+				const minBMI = 18.5;
+				const maxBMI = 24;
+
+				// const minWeight = minBMI * (height * height);
+				// const maxWeight = maxBMI * (height * height);
+				const minWeight = ((minBMI * (height * height))).toFixed(1);
+				const maxWeight = ((maxBMI * (height * height))).toFixed(1);
+
+				return {
+					minWeight: minWeight,
+					maxWeight: maxWeight
+				}
+			},
+		}
+	}
+</script>
+
+<style>
+	page{
+		background-color: #ffffff;
+	}
+	.BMI{
+		font-size: 60px;
+		font-weight: 1000;
+	}
+	.wight-head{
+		color: #666666;
+		font-size: 14px;
+		letter-spacing: 1px;
+	}
+	.bmi-bar {
+	  width: 100%;
+	  height: 10px;
+	  background: linear-gradient(to right, #57bff6, #13d080, #ffb951, #ff7433);
+	  border-radius: 15px;
+	}
+	
+	.bmi-labels {
+	  display: flex;
+	  justify-content: space-between;
+	  align-items: center;
+	  width: 100%;
+	  font-size: 13px;
+	  color: #999999;
+	}
+	
+	.bmi-labels span {
+	  flex: 1;
+	  text-align: center;
+	  margin: 0 5vw;
+	  height: 25px;
+	  line-height: 25px;
+	}
+	
+	.bmi-labels .active {
+	  color: white;
+	  border-radius: 8px;
+	  position: relative;
+	  --active-color: #13d080; /* 默认颜色 */
+	  background-color: var(--active-color);
+	}
+	
+	.bmi-labels .active::before {
+	  content: "";
+	  position: absolute;
+	  top: 100%; /* 三角形位于元素下方 */
+	  left: 50%; /* 水平居中 */
+	  width: 0;
+	  height: 0;
+	  border-left: 5px solid transparent;
+	  border-right: 5px solid transparent;
+	  border-top: 7px solid var(--active-color); /* 使用变量 */
+	  transform: translateX(-50%); /* 确保三角形的中心点位于 .active 元素的中心 */
+	}
+	
+	.bmi-labels .active1 {
+	  --active-color: #57bff6; /* 自定义颜色 */
+	}
+	
+	.bmi-labels .active2 {
+	  --active-color: #13d080; /* 自定义颜色 */
+	}
+	
+	.bmi-labels .active3 {
+	  --active-color: #ffb951; /* 自定义颜色 */
+	}
+	
+	.bmi-labels .active4 {
+	  --active-color: #ff7433; /* 自定义颜色 */
+	}
+	
+	.bmi-values {
+	  display: flex;
+	  justify-content: space-between;
+	  align-items: center;
+	  width: 100%;
+	  bottom: -30px;
+	  font-size: 14px;
+	  color: #b1b1b1;
+	}
+	
+	.sug-head {
+		font-size: 14px;
+		color: #8d93ad;
+	}
+	
+	.sug-title{
+		font-size: 18px;
+		color: #000;
+		font-weight: 700;
+	}
+	
+	.sug-res{
+		font-size: 16px;
+		color: #999999;
+		font-weight: 500;
+	}
+	
+	.image_bmi{
+		width: 60px;
+		height: 60px;
+	}
+
+</style>

+ 642 - 0
chexnet-master-MP/pages/ai/ai.vue

@@ -0,0 +1,642 @@
+<template>
+	<view>
+		<!-- <view class="tips color_fff size_12 align_c" :class="{ 'show':ajax.loading }" @tap="getHistoryMsg">{{ajax.loadText}}</view> -->
+		<!-- <image @click="openpopup" class="history" src="/static/img/ai.png"></image> -->
+		<view class="box-1">
+			<view class="talk-list">
+				<view v-for="(item,index) in talkList" :key="index" :id="`msg-${item.id}`">
+					<view class="item flex_col" :class=" item.type == 1 ? 'push':'pull' ">
+						<image v-if="item.pic" :src="item.pic" mode="aspectFill" class="pic"></image>
+						<view class="content">{{item.content}}</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		
+		<view class="box-2">
+			<view class="flex_col" :style="{position: 'relative',bottom:inputHeight+'px'}">
+				<image @click="openpopup" class="history" src="/static/img/ai.png"></image>
+				<view class="flex_grow">
+					<input @confirm="send" :adjust-position="false" @focus="inputBindFocus" 
+						@blur="inputBindBlur" type="text" class="content" v-model="content" 
+						placeholder="请输入聊天内容" placeholder-style="color:#DDD;" 
+						:cursor-spacing="6" @click="$content_check.checkLogin" :disabled="$content_check.isDisabled"
+					/>
+				</view>
+				<button class="send" @tap="send">发送</button>
+			</view>
+		</view>
+		
+		<uv-popup ref="popup" mode="left" bgColor="#f5f5f5" style="overflow-y: scroll;" >
+			<scroll-view class="popup scroll-Y" scroll-y="true">
+				<view class="chart-con">
+					<view class="chart-wrap">
+						<view v-if="ai_talk_history && Object.keys(ai_talk_history).length > 0" class="flex justify-between">
+							<view class="title">
+								<view class="ver-line"></view>
+								<text>AI 问诊记录</text>
+							</view>
+							<button @click="check_delAllHistoryMsg" class="del-button button-all center">删除所有记录</button>
+						</view>
+						
+						<view v-else class="no-data center">暂无数据</view>
+						
+						<uv-gap height="10"></uv-gap>
+						
+						<view @longpress="check_delHistoryMsg(key)" @click="getHistoryMsg(key)" class="history_item" v-if="refresh" v-for="(value, key) in ai_talk_history" :key="key">
+							<view>
+								<text class="block">{{value['timeString']}}</text>
+								<div class="block talk-text"><text style="color: #99d7ff;">{{name}}:</text>{{value['talkList'][1]['content']}}</div>
+								<view class="divider"></view>
+								<div class="block talk-text"><text style="color: #adecaf;">AI:</text>{{value['talkList'][2]['content']}}</div>
+								<view class="divider"></view>
+							</view>
+						</view>
+						<view v-else style="height: 3000px;"></view>
+						<!-- {{ai_talk_history}} -->
+					</view>
+				</view>
+				
+				<button @click="new_talk" class="button-all center new-button">新建对话</button>
+			</scroll-view>
+		</uv-popup>
+	</view>
+</template>
+
+<script>
+	export default {
+		onPullDownRefresh() {
+			setTimeout(() => {uni.stopPullDownRefresh();}, 1000);
+		},
+		onShow() {
+			// 获取全局变量
+			const ai_history = uni.getStorageSync('ai_history');
+			if(ai_history){
+				uni.setStorageSync('ai_history', false);
+				this.openpopup();
+			}
+			
+			// 设置医生性别
+			let doctor_gender = uni.getStorageSync('doctor_gender');
+			if(doctor_gender === 0) this.doctor_gender = 0;
+			else this.doctor_gender = 1;
+			
+			// 设置用户名
+			this.name = uni.getStorageSync("name");
+		},
+		data() {
+			return {
+				
+				doctor_woman: '/static/img/女医生.png',
+				doctor_man: '/static/img/男医生.png',
+				doctor_gender: 1,
+				
+				name: '微信用户',
+				content: '',
+				talkList: [],
+				ai_talk_history: null,
+				timestamp: null,
+				
+				request: 1,
+				// ajax:{
+				// 	rows:20,	//每页数量
+				// 	page:1,	//页码
+				// 	flag:true,	// 请求开关
+				// 	loading:true,	// 加载中
+				// 	loadText:'正在获取消息'
+				// },
+				
+				inputHeight: 0,
+				refresh: true,
+				
+			}
+		},
+		mounted() {
+			this.new_talk();
+			// this.$nextTick(()=>{
+			// 	this.getHistoryMsg();
+			// });
+		},
+		onPageScroll(e){
+			// if(e.scrollTop<5){
+			// 	this.getHistoryMsg();
+			// }
+		},
+		methods: {
+			new_talk(){
+				this.timestamp = Date.now();
+				this.talkList = [{"id":1,"content":"请问有什么需要帮助的吗?"
+				,"type":0,"pic":this.doctor_gender == 1 ? this.doctor_woman : this.doctor_man}];
+			},
+			openpopup(){
+				this.$refs.popup.open();
+				this.ai_talk_history = this.$util.reversedObject(uni.getStorageSync('ai_talk_history'));
+			},
+			inputBindFocus(e) {
+				if(e.detail.height) {
+					this.inputHeight = e.detail.height - this.getBottomBarHeight(); //这个高度就是软键盘的高度
+					console.log('this.inputHeight: ',this.inputHeight);
+				}
+			},
+			inputBindBlur(){
+				this.inputHeight = 0;
+				this.$content_check.textCheck(this.content, this);
+			},
+			getBottomBarHeight() {
+				let res = uni.getSystemInfoSync();
+				const windowHeight = res.windowHeight; // 屏幕可用高度
+				const screenHeight = res.screenHeight; // 屏幕总高度
+				let bottomBarHeight = screenHeight - windowHeight - getTopHeight();
+				bottomBarHeight = bottomBarHeight > 0 ? bottomBarHeight : 0;
+				
+				console.log('Bottom Bar Height:',bottomBarHeight);
+				return bottomBarHeight;
+				
+				function getTopHeight(){
+					// 状态栏高度
+					const statusBarHeight = uni.getSystemInfoSync().statusBarHeight
+					
+					// #ifdef MP-WEIXIN
+					// 获取微信胶囊的位置信息 width,height,top,right,left,bottom
+					const custom = wx.getMenuButtonBoundingClientRect()
+					// console.log(custom)
+					
+					// 导航栏高度(标题栏高度) = 胶囊高度 + (顶部距离 - 状态栏高度) * 2
+					const navigationBarHeight = custom.height + (custom.top - statusBarHeight) * 2
+					// console.log("导航栏高度:"+navigationBarHeight)
+					
+					// 总体高度 = 状态栏高度 + 导航栏高度
+					const navHeight = navigationBarHeight + statusBarHeight
+					
+					// #endif
+					
+					console.log(navHeight);
+					return navHeight;
+				}
+			},
+			check_delAllHistoryMsg(){
+				uni.showModal({
+					title: '清除历史纪录',
+					content: '是否要清除全部历史纪录?',
+					success: (res) => { 
+						if (res.confirm) 
+							this.delAllHistoryMsg(); 
+					}  
+				})
+			},
+			delAllHistoryMsg(){
+				this.new_talk();
+				
+				this.ai_talk_history = null;
+				
+				uni.setStorageSync('ai_talk_history', {});
+			},
+			check_delHistoryMsg(key){
+				uni.showModal({
+					title: '删除历史纪录',
+					content: '是否要删除此历史纪录?',
+					success: (res) => { 
+						if (res.confirm) 
+							this.delHistoryMsg(key); 
+					}  
+				})	
+			},
+			delHistoryMsg(key){
+				if(this.timestamp == key) this.new_talk();
+				
+				let ai_talk_history = uni.getStorageSync('ai_talk_history');
+				delete ai_talk_history[key];
+				
+				this.ai_talk_history = ai_talk_history;
+				uni.setStorageSync('ai_talk_history', ai_talk_history);
+			},
+			// 获取历史消息
+			getHistoryMsg(key){
+				console.log('key: ',key);
+				this.timestamp = key;
+				this.talkList = this.ai_talk_history[key]['talkList'];
+				this.$refs.popup.close();
+				
+				
+			},
+			// 设置页面滚动位置
+			setPageScrollTo(selector){
+				let view = uni.createSelectorQuery().in(this).select(selector);
+				view.boundingClientRect((res) => {
+					uni.pageScrollTo({
+					    scrollTop:res.top - 30,	// -30 为多显示出大半个消息的高度,示意上面还有信息。
+					    duration: 0
+					});
+				}).exec();
+			},
+			// 隐藏加载提示
+			hideLoadTips(flag){
+				if(flag){
+					this.ajax.loadText = '消息获取成功';
+					setTimeout(()=>{
+						this.ajax.loading = false;
+					},300);
+				}else{
+					this.ajax.loading = true;
+					this.ajax.loadText = '正在获取消息';
+				}
+			},
+			// 发送信息
+			async send(){
+				if(!this.content){
+					uni.showToast({
+						title:'请输入有效的内容',
+						icon:'none'
+					});
+					return ;
+				}
+				
+				if(this.request == 0){
+					uni.showToast({duration:1000,icon:'none',title: '消息发送中,请稍等...'});
+					setTimeout(() => uni.showLoading({title:'正在发送...'}), 1500);
+					return ;
+				}
+				
+				let isCheck = await this.$content_check.textCheck(this.content, this);
+				console.log('isCheck: ',isCheck);
+				if(isCheck !== true) return ;
+				
+				this.request = 0;
+				uni.showLoading({title:'正在发送...'});
+				
+				// 将当前发送信息 添加到消息列表。
+				let data = {
+					"id":new Date().getTime(),
+					"content":this.content,
+					"type":1,
+					"pic":null
+				}
+				this.talkList.push(data);
+				
+				let content = this.content;
+				this.$nextTick(()=>{
+					// 清空内容框中的内容
+					this.content = '';
+					uni.pageScrollTo({
+						scrollTop: 999999,	// 设置一个超大值,以保证滚动条滚动到底部
+						duration: 500
+					});
+				});
+				
+				send_message_ai(content).then(res => {
+					console.log('send: res: ',res);
+					let data = {
+						"id":new Date().getTime(),
+						"content":res,
+						"type":0,
+						"pic":this.doctor_gender == 1 ? this.doctor_woman : this.doctor_man
+					}
+					this.talkList.push(data);
+					uni.hideLoading();
+					uni.pageScrollTo({
+						scrollTop: 999999,	// 设置一个超大值,以保证滚动条滚动到底部
+						duration: 500
+					});
+					this.request = 1;
+					
+					this.save_talk(this.talkList, this.timestamp);
+				}).catch(err => {
+					console.log('send: err: ',err);
+					uni.hideLoading();
+					this.imgshow = false;
+					this.request = 1;
+				});
+			},
+			save_talk(talkList, timestamp){
+				let timeString = this.$util.formatDateTime(timestamp);
+				let talkData = {talkList, timeString};
+				
+				let ai_talk_history = uni.getStorageSync('ai_talk_history');
+				if(ai_talk_history) ai_talk_history[timestamp] = talkData;
+				else{
+					ai_talk_history = {};
+					ai_talk_history[timestamp] = talkData;
+				}
+				uni.setStorageSync('ai_talk_history', ai_talk_history);
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	@import "talk.scss";
+	page{
+		background-color: #f5f5f5;
+		font-size: 28rpx;
+	}
+	.scroll-Y {
+		/* #ifndef MP */
+		height: calc(100vh - 155px);
+		/* #endif */
+		
+		/* #ifdef MP */
+		height: calc(100vh - 65px);
+		/* #endif */
+	}
+	.popup{
+		padding: 10px;
+		width: 75vw;
+		
+		.new-button{
+			color: #666;
+			position: fixed;
+			bottom: 15px;
+			background-color: #d4f4c2;
+			height: 50px;
+			width: calc(100% - 20px);
+			font-size: 15px;
+			font-weight: 550;
+			border-radius: 25px;
+		}
+		
+		.history_item{
+			margin-bottom: 10px;
+			background-color: #fff;
+			border-radius: 20px;
+			padding: 10px 20px 20px;
+			color: #666;
+			font-size: 14px;
+			
+			text{
+				margin: 10px 0;
+			}
+			
+			.talk-text{
+				margin: 10px 0 5px;
+				color: #565;
+				font-weight: 550;
+				font-size: 18px;
+				overflow-wrap: break-word;
+				text-overflow: ellipsis;
+				overflow: hidden;
+				white-space: nowrap;
+			}
+		}
+		.history_item:active{
+			opacity: 0.5;
+		}
+	}
+	.history{
+		width: 32px;
+		height: 32px;
+		margin-right: 5px;
+	}
+	.history:active {
+		opacity: 0.5;
+	}
+	
+	/* 加载数据提示 */
+	.tips{
+		position: fixed;
+		left: 0;
+		top:var(--window-top);
+		width: 100%;
+		z-index: 9;
+		color: #333;
+		// background-color: rgba(0,0,0,0.15);
+		height: 72rpx;
+		line-height: 72rpx;
+		transform:translateY(-80rpx);
+		transition: transform 0.3s ease-in-out 0s;
+		
+		&.show{
+			transform:translateY(0);
+		}
+	}
+	
+	.box-1{
+		width: 100%;
+		height: auto;
+		padding-bottom: 100rpx;
+		box-sizing: content-box;
+		
+		/* 兼容iPhoneX */
+		margin-bottom: 0;  
+		margin-bottom: constant(safe-area-inset-bottom);  
+		margin-bottom: env(safe-area-inset-bottom);  
+	}
+	.box-2{
+		position: fixed;
+		left: 0;
+		width: 100%;
+		bottom: 0;
+		height: auto;
+		z-index: 2;
+		// border-top: #e5e5e5 solid 1px;
+		box-sizing: content-box;
+		background-color: #f5f5f5;
+		
+		/* 兼容iPhoneX */
+		padding-bottom: 0;  
+		padding-bottom: constant(safe-area-inset-bottom);  
+		padding-bottom: env(safe-area-inset-bottom);  
+		
+		>view{
+			padding: 0 20rpx;
+			height: 100rpx;
+		}
+		
+		.content{
+			background-color: #fff;
+			height: 64rpx;
+			padding: 0 20rpx;
+			border-radius: 32rpx;
+			font-size: 28rpx;
+		}
+		
+		.send{
+			background-color: #b7d7a5;
+			color: #fff;
+			height: 64rpx;
+			margin-left: 20rpx;
+			border-radius: 32rpx;
+			padding: 0;
+			width: 120rpx;
+			line-height: 62rpx;
+			
+			&:active{
+				opacity: 1;
+				filter: brightness(80%);
+				transform: translateY(1px) translateX(1px);
+			}
+		}
+	}
+	
+	.talk-list{
+		padding-bottom: 20rpx;
+		
+		/* 消息项,基础类 */
+		.item{
+			padding: 20rpx 20rpx 0 20rpx;
+			align-items:flex-start;
+			align-content:flex-start;
+			color: #333;
+			
+			.pic{
+				width: 92rpx;
+				height: 92rpx;
+				border-radius: 50%;
+				border: #fff solid 1px;
+			}
+			
+			.content{
+				padding: 20rpx;
+				border-radius: 4px;
+				max-width: 500rpx;
+				word-break: break-all;
+				line-height: 52rpx;
+				position: relative;
+			}
+			
+			/* 收到的消息 */
+			&.pull{
+				.content{
+					margin-left: 32rpx;
+					background-color: #fff;
+					
+					&::after{
+						content: '';
+						display: block;
+						width: 0;
+						height: 0;
+						border-top: 16rpx solid transparent;
+						border-bottom: 16rpx solid transparent;
+						border-right: 20rpx solid #fff;
+						position: absolute;
+						top: 30rpx;
+						left: -18rpx;
+					}
+				}
+			}
+			
+			/* 发出的消息 */
+			&.push{
+				/* 主轴为水平方向,起点在右端。使不修改DOM结构,也能改变元素排列顺序 */
+				flex-direction: row-reverse;
+				
+				.content{
+					margin-right: 32rpx;
+					background-color: #c7e7b5;
+				}
+			}
+		}
+	}
+</style>
+
+<style lang="scss" scoped>
+	.no-data{
+		height: 30vw;
+		font-size: 24px;
+		color: #777;
+		padding: 10px;
+	}
+	.del-button{
+		height: 30px;
+		width: 250px;
+		margin-right: 10px;
+		color: #666;
+		background-color: #ffffff;
+	}
+	.chart-con {
+		width: 100%;
+		box-sizing: border-box;
+
+		.chart-wrap {
+			width: 100%;
+			box-sizing: border-box;
+			background-color: #f5f5f5;
+			padding: 32rpx 0rpx;
+			border-radius: 20rpx;
+
+			.title {
+				box-sizing: border-box;
+				width: 100%;
+				padding: 0rpx 28rpx;
+				display: flex;
+				flex-direction: row;
+				justify-content: flex-start;
+				align-items: center;
+			}
+
+			.ver-line {
+				height: 30rpx;
+				width: 8rpx;
+				border-radius: 10rpx;
+				background-color: #4e9d77;
+				margin-right: 5px;
+			}
+
+			.title-desc {
+				font-size: 30rpx;
+				color: #222222;
+				margin-left: 22rpx;
+				font-weight: bold;
+			}
+
+			
+			.line-chart-con {
+				width: 100%;
+				box-sizing: border-box;
+				padding: 0rpx 28rpx;
+
+				.fun-tabs {
+					margin-top: 42rpx;
+					display: flex;
+					flex-direction: row;
+					justify-content: space-between;
+					align-self: center;
+					width: 100%;
+					box-sizing: border-box;
+
+					.tab-item {
+						width: 200rpx;
+						height: 120rpx;
+						border-radius: 10rpx;
+						padding-left: 20rpx;
+						background: #ffffff;
+						border: 1rpx solid #ececec;
+						display: flex;
+						flex-direction: column;
+						justify-content: center;
+						align-items: flex-start;
+						box-sizing: border-box;
+
+						.item-name {
+							color: #6e6e6e;
+							font-size: 20rpx;
+						}
+
+						.item-val {
+							color: #222222;
+							font-size: 24rpx;
+							font-weight: bold;
+							margin-top: 20rpx;
+						}
+					}
+
+					.selected {
+						background: #edf5f1 !important;
+						border: 1rpx solid #4e9d77 !important;
+
+						.item-name {
+							color: #4e9d77 !important;
+						}
+
+						.item-val {
+							color: #4e9d77 !important;
+						}
+					}
+				}
+				.line-chart {
+					margin-top: 30rpx;
+					height: 380rpx;
+				}
+			}
+		}
+	}
+</style>

+ 141 - 0
chexnet-master-MP/pages/health_tip/health_tip.vue

@@ -0,0 +1,141 @@
+<template>
+	<view v-if="health_tip" class="content">
+		<view>
+			<text class="title">健康小知识</text>
+		</view>
+		
+		<uv-gap height="50"></uv-gap>
+		
+		<view class="tip center">
+			<div class="long-text center" v-html="health_tip"></div>
+		</view>
+		
+		<view @click="change_favor" class="flex justify-end relative" style="top: -55vw;">
+			<text v-if="favor" class="favor cuIcon-favorfill text-red"></text>
+			<text v-else class="favor cuIcon-favor"></text>
+		</view>
+		
+		<uv-gap height="50"></uv-gap>
+		
+		<view class="flex justify-between">
+			<button @click="get_health_tip(index - 1)" class="button-all">上一条</button>
+			<button @click="get_health_tip(index + 1)" class="button-all">下一条</button>
+		</view>
+	</view>
+	<view v-else class="no_data"></view>
+</template>
+
+<script>
+	import health_tips from '@/static/health_tip.js'
+	export default {
+		onShow() {
+			this.get_random_health_tip();
+		},
+		data() {
+			return {
+				health_tip: null,
+				index: null,
+				favor: false
+			}
+		},
+		methods: {
+			change_favor(){
+				let favor_health_list = uni.getStorageSync('favor_health_list');
+				if(favor_health_list){
+					if(favor_health_list.includes(this.index)) 
+						favor_health_list.splice(favor_health_list.indexOf(this.index), 1);
+					else favor_health_list.unshift(this.index);
+				}
+				else favor_health_list = [this.index];
+				
+				uni.setStorageSync('favor_health_list',favor_health_list);
+				
+				this.favor = !this.favor;
+			},
+			get_health_tip(index){
+				if(index < 0 || index >= health_tips.length){
+					uni.showToast({duration:1000,icon:'none',title: '到顶了'});
+					return ;
+				}
+				const health_tip = health_tips[index];
+				// 输出随机选取的元素
+				console.log(health_tip);
+				
+				this.favor = false;
+				let favor_health_list = uni.getStorageSync('favor_health_list');
+				if(favor_health_list){
+					if(favor_health_list.includes(index)) this.favor = true;
+				}
+				
+				this.index = index;
+				
+				this.health_tip = formatHealthTip(health_tip);
+				
+				function formatHealthTip(health_tip) {
+				    const totalLength = health_tip.length;
+				    const numRows = Math.ceil(totalLength / 10); // 计算总行数
+				    const charsPerRow = Math.ceil(totalLength / numRows); // 计算每行字符数
+				
+				    let formattedTip = '';
+				    for (let i = 0; i < totalLength; i += charsPerRow) {
+				        formattedTip += health_tip.slice(i, i + charsPerRow) + '<br>';
+				    }
+				
+				    // 去掉最后一行多余的 <br>
+				    formattedTip = formattedTip.slice(0, -4);
+				
+				    return formattedTip;
+				}
+			},
+			get_random_health_tip(){
+				// 获取数组的长度
+				const length = health_tips.length;
+				
+				// 使用 Math.random() 生成一个 [0, length) 范围内的随机索引值
+				const randomIndex = Math.floor(Math.random() * length);
+				
+				this.get_health_tip(randomIndex);
+			}
+		}
+	}
+</script>
+
+<style>
+	page{
+		background-color: #fff;
+	}
+	button{
+		background-color: aliceblue;
+	}
+	.content{
+		padding: 20px;
+	}
+	.tip{
+		height: 55vw;
+		background-color: #f1f3f2;
+		border: none;
+		border-radius: 30px;
+		padding: 20px;
+		letter-spacing: 2px;
+		margin-bottom: 20px;
+		font-weight: 1000;
+		color: #666;
+		font-size: 27px;
+	}
+	.title{
+		color: #777;
+		font-size: 20px;
+		font-weight: 600;
+	}
+	.favor{
+		font-size: 24px;
+		margin-right: 5vw;
+	}
+	.long-text{
+		width: 100vw;
+		overflow: scroll;
+		height: calc(55vw - 40px);
+		overflow-wrap: break-word;
+		text-align: center;
+	}
+</style>

+ 116 - 0
chexnet-master-MP/pages/health_tip/health_tip_collect/health_tip_collect.vue

@@ -0,0 +1,116 @@
+<template>
+	<view v-if="favor_health_list" class="content">
+		<view v-for="(value, key) in favor_health_list" :key="value" class="tip-group">
+			<view class="tip-item flex justify-between">
+				<div class="center" v-html="formatHealthTip(health_tips[value])"></div>
+				<view @click="change_favor(value,key)" class="flex justify-end relative">
+					<text v-if="change_favor_list[key]" class="favor cuIcon-favorfill text-red"></text>
+					<text v-else class="favor cuIcon-favor"></text>
+				</view>
+			</view>
+		</view>
+	</view>
+	<view v-else class="no_data"></view>
+</template>
+
+<script>
+	import health_tips from '@/static/health_tip.js'
+	export default {
+		onLoad() {
+			let favor_health_list = uni.getStorageSync('favor_health_list');
+			if(favor_health_list && Object.keys(favor_health_list).length != 0) this.favor_health_list = favor_health_list;
+			
+			this.change_favor_list = new Array(favor_health_list.length).fill(1);
+		},
+		data() {
+			return {
+				health_tips,
+				favor_health_list: null,
+				change_favor_list: null
+			}
+		},
+		methods: {
+			formatHealthTip(health_tip) {
+			    const totalLength = health_tip.length;
+			    const numRows = Math.ceil(totalLength / 15); // 计算总行数
+			    const charsPerRow = Math.ceil(totalLength / numRows); // 计算每行字符数
+			
+			    let formattedTip = '';
+			    for (let i = 0; i < totalLength; i += charsPerRow) {
+			        formattedTip += health_tip.slice(i, i + charsPerRow) + '<br>';
+			    }
+			
+			    // 去掉最后一行多余的 <br>
+			    formattedTip = formattedTip.slice(0, -4);
+			
+			    return formattedTip;
+			},
+			change_favor(index,key){
+				console.log('index: ',index);
+				console.log('key: ',key);
+				let favor_health_list = uni.getStorageSync('favor_health_list');
+				
+				if(favor_health_list){
+					if(favor_health_list.includes(index)) 
+						favor_health_list.splice(favor_health_list.indexOf(index), 1);
+					else favor_health_list.unshift(index);
+				}
+				else favor_health_list = [index];
+				
+				uni.setStorageSync('favor_health_list',favor_health_list);
+				
+				if(this.change_favor_list[key] == 1) this.change_favor_list[key] = 0;
+				else this.change_favor_list[key] = 1;
+				this.$forceUpdate();
+			},
+		}
+	}
+</script>
+
+<style lang="less">
+	page{
+		background-color: #f5f5f5;
+	}
+	text{
+		font-size: 18px;
+		display: flex;
+		justify-content: center; /* 水平居中 */
+		align-items: center;    /* 垂直居中 */
+	}
+	
+	.content {
+		padding:5px 20px;
+		border: none;
+	}
+	.tip-group{
+		border: none;
+		border-radius: 15px;
+		width: 100%;
+		background-color: #ffffff;
+		margin-bottom: 10px;
+		
+		:first-child{
+			border-radius: 15px 15px 0% 0%;
+		}
+		:last-child{
+			border-radius:0% 0% 15px 15px;
+		}
+		:only-child {
+		    border-radius: 15px;
+		}
+	}
+	.tip-item{
+		font-size: 18px;
+		border: 0px;
+		height: 14vw;
+		padding: 0 10px;
+		background-color: #ffffff;
+	}
+	.tip-item::after {
+	    display: none;
+	}
+	.favor{
+		font-size: 24px;
+		margin-right: 5px;
+	}
+</style>

+ 392 - 0
chexnet-master-MP/pages/img_process/img_process.vue

@@ -0,0 +1,392 @@
+<template>
+	<view class="content">
+		<text v-if="process_show" class="title">x胸腔图病症识别器</text>
+		<text v-else style="color: #666;">{{timeString}}</text>
+		<view class="history">
+			<image @click="$util.navigateTo('/pages/img_process/img_process_history/img_process_history')" src="@/static/img/history_bmi.png"></image>
+			<p style="text-align: center;" class="head-text">历史</p>
+		</view>
+		<uv-gap height="10"></uv-gap>
+		<view v-if="process_show" class="flex justify-center" style="align-items: center; padding: 20px;">
+			<view class="flex justify-between align-center">
+				<uv-upload
+					@oversize="tip()"
+					maxSize=1048576
+					:compressed='false'
+					:fileList="fileList1" 
+					name="1" 
+					:maxCount="1" 
+					@afterRead="afterRead"
+					@delete="deletePic"
+					:previewFullImage="true"
+					width="100" 
+					height="100">
+				</uv-upload>
+				
+				<image v-if="img_url" class="arrow" src="/static/img/右箭头.png" mode="widthFix" style="background-color: #fff;"></image>
+				<image v-if="img_url" :src="img_url" mode="widthFix"></image>
+				
+			</view>
+		</view>
+		
+		<uv-gap v-if="process_show" height="10"></uv-gap>
+		
+		<view v-if="process_show && !processed" class="flex justify-center">
+			<uv-button @click="processImg" color="#1678ff" text="确定" customStyle="width:85vw" customTextStyle="font-weight: 1000;"></uv-button>
+		</view>
+		
+		<uv-gap height="10"></uv-gap>
+		
+		<view v-if="resInfo">
+			<view v-if="resInfo['code']">
+				<h3 v-if="process_show" style="font-weight: 1000;color: #53c21d;">处理成功:</h3>
+				
+				<uv-gap height="5"></uv-gap>
+				
+				<view style="font-size: 16px;">
+					<text style="color: #666;">识别结果:</text>
+					<text style="color: #f56c6c;margin-right: 10px;" v-for="(diseaseValue, diseaseKey) in resInfo['data']['disease']" :key="diseaseKey">{{diseaseValue}}</text>
+				</view>
+				
+				<uv-gap v-if="!process_show" height="20"></uv-gap>
+				
+				<uv-gap height="10"></uv-gap>
+				
+				<view class="diseaseItem" v-for="(diseaseValue, diseaseKey) in resInfo['data']['disease']" :key="diseaseKey">
+				    <text>{{diseaseValue}}:</text>
+					<view>
+				        <text>饮食建议:</text>
+				        <view v-for="(dietValue, dietKey) in resInfo['data'][diseaseValue]['饮食建议']" :key="dietKey">
+				            <text>{{dietValue}}</text>
+				        </view>
+				    </view>
+				    <view>
+				        <text>锻炼建议:</text>
+				        <view v-for="(exerciseValue, exerciseKey) in resInfo['data'][diseaseValue]['锻炼建议']" :key="exerciseKey">
+				            <text>{{exerciseValue}}</text>
+				        </view>
+				    </view>
+				    <view>
+				        <text>睡眠建议:</text>
+				        <view v-for="(sleepValue, sleepKey) in resInfo['data'][diseaseValue]['睡眠建议']" :key="sleepKey">
+				            <text>{{sleepValue}}</text>
+				        </view>
+				    </view>
+				    <view>
+				        <text>用药建议:</text>
+				        <view v-for="(medicationValue, medicationKey) in resInfo['data'][diseaseValue]['用药建议']" :key="medicationKey">
+				            <text>{{medicationValue}}</text>
+				        </view>
+				    </view>
+				</view>
+				
+				<view class="aiSuggest" v-if="aiSuggest">
+					<text>AI 建议</text>
+					<view>
+						<text>{{aiSuggest}}</text>
+					</view>
+				</view>
+				<view v-else class="aiSuggest button-all center" style="height: 50vw;" @click="getAiSuggest">获得ai建议</view>
+				<uv-gap height="30"></uv-gap>
+				<uv-divider text="我是有底线的"></uv-divider>
+				<uv-gap height="30"></uv-gap>
+			</view>
+			<view v-if="!resInfo['code']">
+				<p style="color: #f56c6c; font-size: 18px;">处理失败</p>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import img_api from '@/data/img_api';
+	import send_message_ai from "@/data/medical_ai.js"
+	import disease_suggest from '@/static/disease_suggest.js'
+	
+	export default {
+		onLoad(options) {
+			// 获取传递的对象参数,使用decodeURIComponent解码,并转为对象
+			if ('timestamp' in options) {
+				this.process_show = false;
+				
+				let timestamp = JSON.parse(decodeURIComponent(options.timestamp));
+				this.timestamp = timestamp;
+				console.log('timestamp: ',timestamp);
+				
+				let img_process_history = uni.getStorageSync('img_process_history');
+				
+				let img_process = img_process_history[timestamp];
+				let resInfo = {code: 1, data: {disease: img_process['disease']}};
+				
+				for (let disease of img_process['disease']) {
+					resInfo['data'][disease] = disease_suggest[disease];
+				}
+				this.resInfo = resInfo;
+				
+				this.timeString = img_process['time_string'];
+				
+				if(img_process['ai_suggest']) this.aiSuggest = img_process['ai_suggest'];
+				
+			}
+		},
+		data() {
+			return {
+				process_show: true,
+				uploading: false,
+				style:null,
+				fileList1: [],
+				resInfo: null,
+				img_url: null,
+				aiSuggest: null,
+				timestamp: null,
+				timeString: null,
+				
+				request: 1,
+				processed: false
+			}
+		},
+		methods: {
+			getAiSuggest(){
+				let disease = '';
+				for (let value of this.resInfo['data']['disease']) disease += '、' + value;
+				
+				// 去掉第一个多余的 "、"
+				disease = disease.substring(1);
+				
+				const content = '通过x胸腔图,已知患者有' + disease + "症状,请给出一些建议";
+				console.log('content: ',content);
+				
+				if(this.request == 0){
+					uni.showToast({duration:1000,icon:'none',title: '消息发送中,请稍等...'});
+					setTimeout(() => uni.showLoading({title:'正在发送...'}), 1500);
+					return ;
+				}
+				
+				this.request = 0;
+				uni.showLoading({title:'正在发送...'});
+				
+				send_message_ai(content).then(res => {
+					console.log('send: res: ',res);
+					this.aiSuggest = res;
+					uni.hideLoading();
+					this.request = 1;
+					
+					let img_process_history = uni.getStorageSync('img_process_history');
+					img_process_history[this.timestamp]['ai_suggest'] = res;
+					uni.setStorageSync('img_process_history', img_process_history);
+				}).catch(err => {
+					console.log('send: err: ',err);
+					uni.hideLoading();
+					uni.showToast({duration:1500,icon:'error',title: '获得失败'});
+					this.request = 1;
+				});
+			},
+			// 删除图片
+			deletePic(event) {
+				uni.showModal({
+					title: '提示',
+					content: '确定要删除这个照片吗?',
+					cancelText: '再看看',
+					confirmText: '删除',
+					success: res => {
+						if (res.confirm) {
+							this[`fileList${event.name}`].splice(event.index, 1);
+							this.processed = false;
+							this.aiSuggest = null;
+							this.resInfo = null;
+							this.img_url = null;
+						}
+					}
+				})
+			}, 
+			// 新增图片
+			async afterRead(event) {
+				// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
+				let lists = [].concat(event.file)
+				let fileListLen = this[`fileList${event.name}`].length
+				lists.map((item) => {
+					this[`fileList${event.name}`].push({
+						...item,
+						status: 'uploading',
+						message: '上传中'
+					})
+				});
+				
+				// 使用 Promise.all 来并行检查所有添加的文件
+				await Promise.all(lists.map(async (item, index) => {
+					let addedItem = this[`fileList${event.name}`][fileListLen + index];
+					
+					let isEnable = await this.$content_check.imgCheck(addedItem.thumb);
+					console.log('isEnable: ',isEnable);
+					
+					if(isEnable === true) {
+						addedItem.status = 'success';
+						addedItem.message = '';
+					}
+					else{
+						let indexToRemove = this[`fileList${event.name}`].findIndex(file => file === addedItem);
+						if (indexToRemove !== -1) {
+							this[`fileList${event.name}`].splice(indexToRemove, 1);
+						}
+					}
+				}));
+			},
+			
+			tip(){
+				uni.showToast({
+					icon:"error",
+					title: '图片不能超过1MB',
+				})
+			},
+			processImg() {
+				if(!this.fileList1.length){
+					uni.showToast({
+						icon:"error",
+						title: '请选择图片',
+					})
+				}
+				
+				if(!this.request || this.fileList1[0]['status'] != 'success'){
+					uni.showToast({
+						icon:"none",
+						title: '图片处理中,请稍后...',
+					});
+					
+					return ;
+				}
+				
+				this.request = 0;
+				uni.showLoading({title: '图片处理中...'});
+				img_api(this.fileList1[0]['thumb']).then(res => {
+					console.info('processImg: res: ',res);
+					this.request = 1;
+					this.processed = true;
+					this.resInfo = res;
+					this.img_url = 'data:image/png;base64,' + res['data']['image'];
+					uni.hideLoading();
+					uni.showToast({icon:'success',title: '处理成功',duration:1500});
+					
+					let img_process_history = uni.getStorageSync('img_process_history');
+					const timestamp = Date.now();
+					this.timestamp = timestamp;
+					
+					if(!img_process_history || Object.keys(img_process_history).length === 0) img_process_history = {};
+					
+					img_process_history[timestamp] = {disease: res['data']['disease'], time_string: this.$util.formatDateTime(timestamp)};
+					
+					uni.setStorageSync('img_process_history', img_process_history);
+					
+				}).catch(err => {
+					this.request = 1;
+					this.resInfo = err;
+					
+					console.error('processImg: err: ',err);
+					uni.hideLoading();
+					if(err === 'img_api: 没有token') uni.showToast({icon:'error',title: '未登陆',duration:1500});
+					else uni.showToast({icon:'error',title: '处理失败',duration:1500});
+				});
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	image{
+		height: 100px;
+		width: 100px;
+		background-color: #fff;
+	}
+	.history{
+		position: fixed;
+		top: 10px;
+		right: 20px;
+		background-color: rgba(0, 0, 0, 0);
+		font-size: 12px;
+		color: #666;
+		
+		image{
+			width: 35px;
+			height: 35px;
+			background-color: rgba(0, 0, 0, 0);
+		}
+	}
+	.history:active{
+		opacity: 0.6;
+	}
+	.content{
+		padding:20px;
+	}
+	.arrow{
+		height: 30px;
+		width: 30px;
+		margin: 20px;
+	}
+	.title{
+		color: #777;
+		font-size: 20px;
+		font-weight: 600;
+	}
+	.diseaseItem{
+		background-color: #f1f3f2;
+		border-radius: 30px;
+		padding: 20px;
+		color: #333;
+		letter-spacing: 1px;
+		margin-bottom: 20px;
+		
+		> text{
+			color: #000;
+			font-size: 18px;
+			font-weight: 600;
+		}
+		
+		> view{
+			border-radius: 20px;
+			margin: 15px 0 5px;
+			background-color: #ffffff;
+			border-radius: 20px;
+			padding: 15px;
+			
+			> text{
+				font-size: 16px;
+				color: #222;
+			}
+			view{
+				padding: 1px 0;
+				text{
+					font-size: 15px;
+				}
+			}
+		}
+	}
+	
+	.aiSuggest{
+		background-color: #f1f3f2;
+		border: none;
+		border-radius: 30px;
+		padding: 20px;
+		letter-spacing: 1px;
+		margin-bottom: 20px;
+		font-weight: 1000;
+		color: #666;
+		font-size: 28px;
+		
+		> text{
+			color: #000;
+			font-size: 18px;
+			font-weight: 600;
+		}
+		
+		> view{
+			border-radius: 20px;
+			margin: 10px 0;
+			background-color: #ffffff;
+			border-radius: 20px;
+			padding: 15px;
+			
+			> text{
+				font-size: 15px;
+			}
+		}
+	}
+</style>

+ 201 - 0
chexnet-master-MP/pages/img_process/img_process_history/img_process_history.vue

@@ -0,0 +1,201 @@
+<template>
+	<view class="content">
+		<view v-if="!img_process_history || Object.keys(img_process_history).length === 0" class="no_data"></view>
+		<view v-else v-for="(value, key) in img_process_history" :key="key" class="img-history-item">
+			<view @longpress="check_del_img_history(key)" @click="$util.navigateTo(`/pages/img_process/img_process?timestamp=${key}`)" class="flex justify-between">
+				<view>
+					<view class="flex justify-start margin-bottom-xs">
+						<text class="title center">检测结果:</text>
+						<text class="result center" v-for="(value, key) in value['disease']">{{value}}</text>
+					</view>
+					
+					<view class="time align-center">{{value['time_string']}}</view>
+				</view>
+				
+				<view @click.stop="openpopup(key)" class="center relationship">
+					<text v-if="value['relationship']">{{family_list[value['relationship']]['name']}}</text>
+					<text v-else style="text-decoration: underline; color: #666;">关联成员</text>
+				</view>
+			</view>
+		</view>
+		<uv-popup ref="popup" mode="right" bgColor="#f5f5f5" style="overflow-y: scroll;" >
+			<scroll-view class="popup scroll-Y" scroll-y="true">
+				<view v-if="!family_list" class="no-data center">暂无成员</view>
+				<view v-else v-for="(value, key) in family_list" :key="key" class="family-item">
+					<view @click="addrelationship(key)" class="flex justify-between">
+						<view>
+							<view class="flex justify-start margin-bottom-xs">
+								<text class="name center">{{value['name']}}</text>
+								<text v-if="value['relationship']" class="relationship center">{{value['relationship']}}</text>
+							</view>
+							
+							<text class="gender">性别:{{ value['gender'] === 0 ? '男' : (value['gender'] === 1 ? '女' : '未知') }}</text>
+							
+							<text v-if="value['age']" class="age">年龄:{{value['age']}}岁</text>
+						</view>
+						<text class="cuIcon-right center"></text>
+					</view>
+				</view>
+			</scroll-view>
+		</uv-popup>
+	</view>
+</template>
+
+<script>
+	export default {
+		onShow() {
+			let img_process_history = uni.getStorageSync('img_process_history');
+			this.img_process_history = this.$util.reversedObject(img_process_history);
+			
+			this.family_list = uni.getStorageSync('family_list');
+		},
+		onPullDownRefresh() {
+			let img_process_history = uni.getStorageSync('img_process_history');
+			this.img_process_history = this.$util.reversedObject(img_process_history);
+			
+			this.family_list = uni.getStorageSync('family_list');
+		},
+		data() {
+			return {
+				img_process_history: null,
+				family_list: null,
+				selectitem: null,
+			}
+		},
+		methods: {
+			addrelationship(key){
+				let img_process_history = uni.getStorageSync('img_process_history');
+				
+				img_process_history[this.selectitem]['relationship'] = key;
+				
+				uni.setStorageSync('img_process_history', img_process_history);
+				this.img_process_history = this.$util.reversedObject(img_process_history);
+				
+				this.$refs.popup.close();
+			},
+			openpopup(selectitem){
+				this.selectitem = selectitem;
+				this.$refs.popup.open();
+			},
+			check_del_img_history(key){
+				uni.showModal({
+					title: '删除记录',
+					content: ' 是否要删除此记录?',
+					success: (res) => { 
+						if (res.confirm) this.del_img_history(key); 
+					}  
+				})	
+			},
+			del_img_history(key){
+				let img_process_history = uni.getStorageSync('img_process_history');
+				delete img_process_history[key];
+				
+				this.img_process_history = this.$util.reversedObject(img_process_history);
+				uni.setStorageSync('img_process_history', img_process_history);
+				
+				this.$forceUpdate();
+			},
+		}
+	}
+</script>
+
+<style lang="less" scoped>
+	.popup{
+		padding: 10px;
+		width: 75vw;
+		
+		.family-item{
+			background-color: #fff;
+			border-radius: 20px;
+			height: 80px;
+			margin-bottom: 10px;
+			padding: 10px 18px;
+			
+			color: #666;
+			letter-spacing: 1px;
+			
+			.name{
+				letter-spacing: 2px;
+				font-size: 20px;
+				font-weight: 550;
+				color: #555;
+			}
+			
+			.gender{
+				margin-right: 20px;
+			}
+			
+			.relationship{
+				color: #555;
+				font-size: 16px;
+				height: 24px;
+				width: 60px;
+				border-radius: 10px;
+				letter-spacing: 0px;
+				margin-left: 20px;
+				background-color: #ebf6ff;
+			}
+		}
+	}
+	.no-data{
+		height: 30vw;
+		font-size: 24px;
+		color: #777;
+		padding: 10px;
+		background-color: #fff;
+		border-radius: 20px;
+	}
+	.content{
+		padding: 10px 20px;
+		border: none;
+		background-color: #f6f6f6;
+		height: 100vh;
+	}
+	.scroll-Y {
+		/* #ifndef MP */
+		height: calc(100vh - 155px);
+		/* #endif */
+		
+		/* #ifdef MP */
+		height: calc(100vh - 65px);
+		/* #endif */
+	}
+	.relationship{
+		z-index: 100;
+		color: #666;
+		font-size: 16px;
+		margin: 5px 0;
+		width: 85px;
+		border-radius: 10px;
+		letter-spacing: 0px;
+		background-color: #ebf6ff;
+	}
+	.img-history-item{
+		background-color: #fff;
+		border-radius: 20px;
+		height: 80px;
+		margin-bottom: 20px;
+		padding: 15px;
+		
+		color: #666;
+		letter-spacing: 1px;
+		
+		.title{
+			letter-spacing: 2px;
+			font-size: 18px;
+			font-weight: 550;
+			color: #555;
+		}
+		
+		.result{
+			font-size: 17px;
+			font-weight: 550;
+			color: #f56c6c;
+			margin-right: 10px;
+		}
+		
+		.time{
+			margin-top: 8px;
+		}
+	}
+</style>

+ 158 - 114
chexnet-master-MP/pages/index/index.vue

@@ -1,15 +1,5 @@
 <template>
 	<view>
-		<!-- <view class="header-index">
-			<text class="header-title">智疗助手</text>
-			<navigator v-if="name" @click="to_home" class="header-login">您好:{{name}}</navigator>
-			<navigator v-else url="/pages/login/login" class="header-login">登录/注册</navigator>
-		</view> -->
-		
-		<!-- <uv-swiper class="button-all" 
-			bgColor="background-color: rgba(0, 0, 0, 0);" 
-			style="margin:0 -15px;height: calc(25vh - 15px);" height="25vh" imgMode="aspectFill" indicator indicatorMode="dot" :list="list">
-		</uv-swiper> -->
 		
 		<image class="top-img" src="@/static/img/lbt1.jpg"></image>
 		
@@ -19,28 +9,37 @@
 			</view> -->
 			<view @click="to_ai()" class="large-button button-all" style="background-color: #d4f4c2;"><!-- blanchedalmond -->
 				<view class="align-center flex justify-between">
-					<image style="height: 25vw; width: 25vw; margin-left: 0vw;" src="@/static/img/ai-talk.png"></image>
-					<p style="color: #5c6a7c; font-size: 30px; margin-left: 3vw;">AI 问诊</p>
+					<image style="height: 22vw; width: 22vw; margin-left: -3vw;" src="@/static/img/ai-talk.png"></image>
+					<p style="color: #5c6a7c; font-size: 30px; margin-left: 4vw;">AI 问诊</p>
 				</view>
 			</view>
 			
 			<view @click="$util.navigateTo('/pages/img_process/img_process')" class="large-button button-all" style="background-color: blanchedalmond;"><!-- blanchedalmond -->
 				<view class="align-center flex justify-between">
-					<image style="height: 23vw; width: 23vw; margin-left: 0vw;" src="@/static/img/识别.png"></image>
-					<p style="color: #5c6a7c; font-size: 28px; margin-left: 3vw;">病例识别</p>
+					<image style="height: 20vw; width: 20vw; margin-left: 2vw;" src="@/static/img/识别.png"></image>
+					<p style="color: #5c6a7c; font-size: 28px; margin-left: 4vw;">病例识别</p>
 				</view>
 			</view>
 			
-			<view @click="$util.navigateTo('/pages/BMI/BMI')" class="large-button button-all" style="background-color: aliceblue;">
+			<view @click="$util.navigateTo('/pages/health_tip/health_tip')" class="large-button button-all" style="background-color: aliceblue;">
 				<view class="align-center flex justify-between">
-					<image style="height: 25vw; width: 25vw; margin-left: 0vw;" src="@/static/img/bmi.png"></image>
-					<p style="color: #5c6a7c; font-size: 30px; margin-left: 12vw;">B M I</p>
+					<image style="height: 22vw; width: 22vw; margin-left: 5vw;" src="@/static/img/health-tip.png"></image>
+					<p style="color: #5c6a7c; font-size: 26px; margin-left: 4vw;">健康小知识</p>
 				</view>
 			</view>
 			
-			<view>
-				<image style="height: 30vw;width: 30vw; margin-top: auto; position: fixed; bottom: 0vh; left: -2vw;" src="@/static/img/doctor.png"></image>
-				<view v-if="isTalking" :style="{ width: talkWidth }" class="talk">{{message}}</view>
+			<view @click="$util.navigateTo('/pages/BMI/BMI')" class="large-button button-all" style="background-color: #fff1f1;"> <!-- #fffae8 #fff0ff-->
+				<view class="align-center flex justify-between">
+					<image style="height: 22vw; width: 22vw; margin-left: 0vw;" src="@/static/img/bmi.png"></image>
+					<p style="color: #5c6a7c; font-size: 30px; margin-left: 10vw;">B M I</p>
+				</view>
+			</view>
+			
+			<uv-gap height="20vw"></uv-gap>
+			
+			<view v-if="windowHeight">
+				<image @click="to_ai()" :style="{top:`calc(${windowHeight}px - 30vw)`}" class="doctor" :src="doctor_gender == 1 ? doctor_woman : doctor_man"></image>
+				<view v-if="isTalking" :style="{ width: `${talkWidth}`, top:`calc(${windowHeight}px - 18vw)` }" class="talk">{{message}}</view>
 			</view>
 			<!-- <uv-button @click="$util.navigateTo('/pages/test/test')"></uv-button> -->
 		</view>
@@ -48,111 +47,149 @@
 </template>
 
 <script>
-export default {
-	onLoad() {
-		this.$user_api.check_login();
-	},
-	mounted(){
-		this.talk();
-	},
-	onShow() {
-		this.name = uni.getStorageSync("name");
-	},
-	onPullDownRefresh() {
-		this.name = uni.getStorageSync("name");
-		setTimeout(() => {uni.stopPullDownRefresh();}, 1000);
-	},
-	data() {
-		return {
-			name: null,
-			time: 1,
-			message: '您好 !',
-			message_num: 0,
-			talkWidth: '30vw',
-			isTalking: true
-			// list: [
-			// 	'../../static/img/lbt1.jpg',
-			// 	'../../static/img/lbt2.jpg',
-			// 	'../../static/img/lbt3.jpg'
-			// ]
-		};
-	},
-	methods: {
-		to_ai(){
-			uni.switchTab({
-				url: '/pages/ai/ai'
-			})
+	export default {
+		onShow() {
+			let doctor_gender = uni.getStorageSync('doctor_gender');
+			if(doctor_gender === 0) this.doctor_gender = 0;
+			else this.doctor_gender = 1;
+			console.log('doctor_gender: ',this.doctor_gender);
+			
 		},
-		to_home(){
-			uni.switchTab({
-				url: '/pages/my/my'
-			})
+		onReady() {
+			const windowHeight = uni.getSystemInfoSync().windowHeight - getBottomBarHeight();
+			this.windowHeight = windowHeight;
+			console.log('windowHeight-init: ',windowHeight);
+			
+			function getBottomBarHeight() {
+				let res = uni.getSystemInfoSync();
+				const windowHeight = res.windowHeight; // 屏幕可用高度
+				const screenHeight = res.screenHeight; // 屏幕总高度
+				
+				// 状态栏高度
+				const statusBarHeight = res.statusBarHeight
+				
+				// #ifdef MP-WEIXIN
+				// 获取微信胶囊的位置信息 width,height,top,right,left,bottom
+				const custom = wx.getMenuButtonBoundingClientRect()
+				// console.log(custom)
+				
+				// 导航栏高度(标题栏高度) = 胶囊高度 + (顶部距离 - 状态栏高度) * 2
+				const navigationBarHeight = custom.height + (custom.top - statusBarHeight) * 2
+				// console.log("导航栏高度:"+navigationBarHeight)
+				
+				// 总体高度 = 状态栏高度 + 导航栏高度
+				const navHeight = navigationBarHeight + statusBarHeight
+				
+				// #endif
+				
+				let bottomBarHeight = screenHeight - windowHeight - navHeight;
+				bottomBarHeight = bottomBarHeight > 0 ? bottomBarHeight : 0;
+				
+				console.log('Bottom Bar Height:',bottomBarHeight);
+				
+				return bottomBarHeight;
+			}
+		},
+		onLoad() {
+			this.$user_api.check_login();
+		},
+		mounted(){
+			this.talk();
 		},
-		talk(){
-			return new Promise((resolve, reject) => {
-				if(this.message_num < 6){
-					if(this.message_num == 1) {
-						this.talkWidth = '30vw';
-						const hour = new Date().getHours();
-						console.log('hour: ',hour);
-						if (hour >= 4 && hour < 8) {
-							this.message = '早上好 !'; // 早上
-						} else if (hour >= 8 && hour < 12) {
-							this.message = '上午好 !'; // 上午
-						} else if (hour >= 12 && hour < 18) {
-							this.message = '下午好 !'; // 下午
-						} else {
-							this.message = '晚上好 !'; // 晚上
+		onPullDownRefresh() {
+			setTimeout(() => {uni.stopPullDownRefresh();}, 1000);
+		},
+		data() {
+			return {
+				windowHeight: null,
+				
+				doctor_woman: '/static/img/女医生.png',
+				doctor_man: '/static/img/男医生.png',
+				doctor_gender: 1,
+				name: null,
+				time: 1,
+				message: '您好 !',
+				message_num: 0,
+				talkWidth: '30vw',
+				isTalking: true
+				// list: [
+				// 	'../../static/img/lbt1.jpg',
+				// 	'../../static/img/lbt2.jpg',
+				// 	'../../static/img/lbt3.jpg'
+				// ]
+			};
+		},
+		methods: {
+			to_ai(){
+				uni.switchTab({
+					url: '/pages/ai/ai'
+				})
+			},
+			to_home(){
+				uni.switchTab({
+					url: '/pages/my/my'
+				})
+			},
+			talk(){
+				return new Promise((resolve, reject) => {
+					if(this.message_num < 6){
+						if(this.message_num == 1) {
+							this.talkWidth = '30vw';
+							const hour = new Date().getHours();
+							console.log('hour: ',hour);
+							if (hour >= 4 && hour < 8) {
+								this.message = '早上好 !'; // 早上
+							} else if (hour >= 8 && hour < 12) {
+								this.message = '上午好 !'; // 上午
+							} else if (hour >= 12 && hour < 18) {
+								this.message = '下午好 !'; // 下午
+							} else {
+								this.message = '晚上好 !'; // 晚上
+							}
+							this.applyAnimation();
 						}
-						this.applyAnimation();
-					}
-					if(this.message_num == 2) {
-						this.talkWidth = '60vw';
-						this.message = '希望您今天过得愉快。';
-						this.applyAnimation();
-					}
-					if(this.message_num == 3) {
-						this.talkWidth = '65vw';
-						this.message = '有什么我可以帮您的吗?';
-						this.applyAnimation();
+						if(this.message_num == 2) {
+							this.talkWidth = '60vw';
+							this.message = '希望您今天过得愉快。';
+							this.applyAnimation();
+						}
+						if(this.message_num == 3) {
+							this.talkWidth = '65vw';
+							this.message = '有什么我可以帮您的吗?';
+							this.applyAnimation();
+						}
+						if(this.message_num == 4) {
+							this.talkWidth = '60vw';
+							this.message = '注意休息,保持健康。';
+							this.applyAnimation();
+						}
+						
+						this.message_num = this.message_num + 1;
+						// console.log('this.message_num: ',this.message_num);
+						setTimeout(() => this.talk(), 3000);
 					}
-					if(this.message_num == 4) {
-						this.talkWidth = '60vw';
-						this.message = '注意休息,保持健康。';
-						this.applyAnimation();
+					else{
+						this.message_num = 0;
+						setTimeout(() => this.talk(), 3000);
 					}
-					
-					this.message_num = this.message_num + 1;
-					// console.log('this.message_num: ',this.message_num);
-					setTimeout(() => this.talk(), 3000);
-				}
-				else{
-					this.message_num = 0;
-					setTimeout(() => this.talk(), 3000);
-				}
-			})
-		},
-		applyAnimation() {
-			this.isTalking = false;
-			setTimeout(() => this.isTalking = true, 100);
-		},
-	}
-};
+				})
+			},
+			applyAnimation() {
+				this.isTalking = false;
+				setTimeout(() => this.isTalking = true, 100);
+			},
+		}
+	};
 </script>
-<!-- 
-		background-image: url('@/static/img/background.jpg');
-		background-position: top center; /* 图片定位到顶部中心 */
-		background-repeat: no-repeat; /* 防止图片重复 */
-		background-size: 100% auto; /* 宽度覆盖整个容器,高度按比例调整 */-->
 
 <style>
 	page {
 		height: 100vh;
+		background-color: #fff;
 	}
 	
 	.container {
-		background-color: #ffffff;
-		margin: 0 15px;
+		margin: 0 20px;
 		display: flex;
 		flex-direction: column;
 		height: 80vh;
@@ -220,15 +257,22 @@ export default {
 		justify-content: center;
 		align-items: center;
 		width: 100%;
-		height: 16vh;
+		height: 40vw;
 		margin-top: 20px;
 		width: 100%;
 		font-weight: 1000;
 	}
 	
+	.doctor{
+		height: 30vw;
+		width: 30vw;
+		margin-top: auto;
+		position: fixed;
+		left: -2vw;
+	}
+	
 	.talk {
 		position: fixed;
-		bottom: 4vh;
 		left: 30vw;
 		width: 30vw;
 		height: 40px;

+ 15 - 3
chexnet-master-MP/pages/login/login.vue

@@ -17,7 +17,10 @@
 							<uv-gap height="10" ></uv-gap>
 							
 							<view class="flex justify-between">
-								<input maxlength=20 class="" type="nickname" style="width: 60%;" v-model="user.name" placeholder-style="color: #cccccc; font-size: 24px; font-weight: 100;" placeholder="请输入昵称" />
+								<input maxlength=20 class="" type="nickname" style="width: 60%;" v-model="user.name" 
+									placeholder-style="color: #cccccc; font-size: 24px; font-weight: 100;" 
+									placeholder="请输入昵称"
+								/>
 								<image src="../../static/img/user.png" style="background-color: #fff;width: 15vw;height: 15vw;margin: 0 30px 5px;"></image>
 							</view>
 						</view>
@@ -44,7 +47,7 @@
 						<view class="" style="margin-bottom: -20upx;"><!-- 年龄 -->
 							<view class="title">年龄</view>
 							<uv-gap height="10" ></uv-gap>
-							<input class="weui-input" type="number" v-model="user.age" placeholder-style="color: #cccccc; font-size: 24px; font-weight: 100;" placeholder="请输入年龄" />
+							<input maxlength=3 class="weui-input" type="number" v-model="user.age" placeholder-style="color: #cccccc; font-size: 24px; font-weight: 100;" placeholder="请输入年龄" />
 						</view>
 						<uv-divider customStyle="margin: 0 0"></uv-divider>
 						
@@ -83,6 +86,9 @@
 			}
 		},
 		methods: {	
+			// inputBindBlur(){
+			// 	this.$content_check.textCheck(this.user.name, this, 'user.name');
+			// },
 			changegender() {
 				this.$refs.picker.open();
 			},
@@ -97,6 +103,7 @@
 			login(){
 				if(this.request){
 					this.request = 0;
+					
 					uni.showLoading({title: '加载中...'});
 					console.log('this.user: ',this.user);
 					this.$user_api.user_login()
@@ -117,7 +124,7 @@
 						});
 				}
 			},
-			update(){
+			async update(){
 				if(this.user.name.length > 0){
 					//用户名必须由1到20个字符组成,并且只能包含字母和数字。
 					const regex = /^[a-zA-Z0-9\u4e00-\u9fa5]{1,20}$/;
@@ -127,6 +134,11 @@
 						console.log("用户名有效");
 						
 						if(this.request){
+							
+							let isCheck = await this.$content_check.textCheck(this.user.name, this, 'user.name');
+							console.log('isCheck: ',isCheck);
+							if(isCheck !== true) return ;
+							
 							this.request = 0;
 							uni.showLoading({title: '加载中...'});
 							this.$user_api.user_update(this.$util.removeNullValues(this.user))

+ 110 - 0
chexnet-master-MP/pages/my/family/family.vue

@@ -0,0 +1,110 @@
+<template>
+	<view>
+		<view class="top-back"></view>
+		<view class="content">
+			<view v-if="!family_list || Object.keys(family_list).length === 0" class="no_data"></view>
+			<view v-else v-for="(value, key) in family_list" :key="key" class="family-item">
+				<view @longpress="check_del_family(key)" @click="$util.navigateTo(`/pages/my/family/family_info/family_info?id=${key}`)" class="flex justify-between">
+					<view>
+						<view class="flex justify-start margin-bottom-xs">
+							<text class="name center">{{value['name']}}</text>
+							<text v-if="value['relationship']" class="relationship center">{{value['relationship']}}</text>
+						</view>
+						
+						<text class="gender">性别:{{ value['gender'] === 0 ? '男' : (value['gender'] === 1 ? '女' : '未知') }}</text>
+						
+						<text v-if="value['age']" class="age">年龄:{{value['age']}}岁</text>
+					</view>
+					<text class="cuIcon-right center"></text>
+				</view>
+			</view>
+			
+			<uv-gap height="60"></uv-gap>
+			<button @click="$util.navigateTo('/pages/my/family/family_info/family_info')" class="bottom-button center">新增成员</button>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		onShow() {
+			this.family_list = uni.getStorageSync('family_list');
+		},
+		onPullDownRefresh() {
+			this.family_list = uni.getStorageSync('family_list');
+		},
+		data() {
+			return {
+				family_list: null,
+			}
+		},
+		methods: {
+			check_del_family(key){
+				uni.showModal({
+					title: '删除成员',
+					content: ' 是否要删除此成员?',
+					success: (res) => { 
+						if (res.confirm) this.del_family(key); 
+					}  
+				})	
+			},
+			del_family(key){
+				let family_list = uni.getStorageSync('family_list');
+				delete family_list[key];
+				
+				this.family_list = family_list;
+				uni.setStorageSync('family_list', family_list);
+				
+				this.$forceUpdate();
+			},
+		}
+	}
+</script>
+
+<style lang="less" scoped>
+	.family-item{
+		background-color: #fff;
+		border-radius: 20px;
+		height: 80px;
+		margin-top: 20px;
+		padding: 15px;
+		
+		color: #666;
+		letter-spacing: 1px;
+		
+		.name{
+			letter-spacing: 2px;
+			font-size: 20px;
+			font-weight: 550;
+			color: #555;
+		}
+		
+		.gender{
+			margin-right: 20px;
+		}
+		
+		.relationship{
+			color: #555;
+			font-size: 17px;
+			height: 28px;
+			width: 75px;
+			border-radius: 10px;
+			letter-spacing: 0px;
+			margin-left: 20px;
+			background-color: #ebf6ff;
+		}
+	}
+	.top-back{
+		height: 35px;
+		background-color: #1678ff;
+		color: #fff;
+		margin-bottom: -25px;
+	}
+	.content{
+		padding: 10px 20px;
+		border-radius: 25px 25px 0 0;
+		border: none;
+		background-color: #f6f6f6;
+		height: 100vh;
+	}
+</style>

+ 214 - 0
chexnet-master-MP/pages/my/family/family_info/family_info.vue

@@ -0,0 +1,214 @@
+<template>
+	<view>
+		<view class="top-back"></view>
+		<view class="content">
+			<view class="margin-top" >
+				<uv-gap height="10" ></uv-gap>
+				
+				<!-- <p style="font-size: 25px;">个人信息</p> -->
+				<uv-divider class="head-text" :text="title" textSize="26" textColor="#000"></uv-divider>
+				
+				<uv-gap height="10" ></uv-gap>
+				
+				<view class="margin-top"><!-- 昵称 -->
+					<view class="title">昵称</view>
+					<uv-gap height="10" ></uv-gap>
+					
+					<view class="flex justify-between">
+						<input maxlength=20 type="text" style="width: 60%;" v-model="family.name" 
+							placeholder-style="color: #cccccc; font-size: 24px; font-weight: 100;" placeholder="请输入昵称" 
+							@click="$content_check.checkLogin" :disabled="$content_check.isDisabled"
+							@blur="inputBindBlur('name')"
+						/>
+						<image src="@/static/img/user.png" style="background-color: #fff;width: 15vw;height: 15vw;margin: 0 30px 5px;"></image>
+					</view>
+				</view>
+				<uv-divider customStyle="margin: 0 0"></uv-divider>
+				
+				<uv-gap height="20" ></uv-gap>
+				
+				<view style="margin-bottom: -20upx;"><!-- 关系 -->
+					<view class="title">关系</view>
+					<uv-gap height="10" ></uv-gap>
+					
+					<view class="flex justify-between">
+						<input maxlength=10 type="text" style="width: 60%;" v-model="family.relationship" 
+							placeholder-style="color: #cccccc; font-size: 24px; font-weight: 100;" placeholder="请输入成员关系" 
+							@click="$content_check.checkLogin" :disabled="$content_check.isDisabled"
+							@blur="inputBindBlur('relationship')"
+						/>
+						<image src="@/static/img/family.png" style="background-color: #fff;width: 15vw;height: 15vw;margin: 0 30px 15px;"></image>
+					</view>
+				</view>
+				<uv-divider customStyle="margin: 0 0"></uv-divider>
+				
+				<uv-gap height="20" ></uv-gap>
+				
+				<view><!-- 性别 -->
+					<view>
+						<view class="title">性别</view>
+						<uv-gap height="10" ></uv-gap>
+						<view class="flex justify-between">
+							<input placeholder="请选择性别" disabled="disabled" style="width: 60%;" name="input" v-model="gender" placeholder-style="color: #cccccc; font-size: 24px; font-weight: 100;" @click="changegender"></input>
+							<image @click="confirm({'indexs': [0]})" src="@/static/img/man.png" style="background-color: #fff;width: 15vw;height: 15vw;"></image>
+							<image @click="confirm({'indexs': [1]})" src="@/static/img/woman.png" style="background-color: #fff;width: 15vw;height: 15vw;"></image>
+						</view>
+					</view>
+					<uv-picker ref="picker" :columns="columns" @confirm="confirm"></uv-picker>
+				</view>
+				<uv-divider customStyle="margin: 0 0"></uv-divider>
+				
+				<uv-gap height="20" ></uv-gap>
+				
+				<view style="margin-bottom: -20upx;"><!-- 年龄 -->
+					<view class="title">年龄</view>
+					<uv-gap height="10" ></uv-gap>
+					<input maxlength=3 type="number" v-model="family.age" placeholder-style="color: #cccccc; font-size: 24px; font-weight: 100;" placeholder="请输入年龄" />
+				</view>
+				<uv-divider customStyle="margin: 0 0"></uv-divider>
+				
+				<uv-gap height="10" ></uv-gap>
+				
+			</view>	
+			<uv-modal width=260 ref="modal" title="请将信息填写完整"  @confirm="confirm"></uv-modal>				
+		</view>
+		
+		<uv-button @click="update()" customStyle="position: fixed; bottom: 40px;width: calc(100vw - 60px);margin: 0 30px" shape="circle" size="large" color="#1678ff">{{button_text}}</uv-button>
+	</view>
+</template>
+
+<script>
+	export default {
+		onLoad(options) {
+			// 获取传递的对象参数,使用decodeURIComponent解码,并转为对象
+			if ('id' in options) {
+				let id = JSON.parse(decodeURIComponent(options.id));
+				this.family.id = id;
+				this.family = uni.getStorageSync("family_list")[id];
+				this.gender = this.family.gender === 0 ? '男' : '女';
+			}
+			else{
+				let title = '新增成员';
+				let button_text = '新增';
+				uni.setNavigationBarTitle({title});
+				this.title = title;
+				this.button_text = button_text;
+				
+				let family_list = uni.getStorageSync('family_list');
+				if(!family_list || Object.keys(family_list).length == 0) this.family.id = 1;
+				else{
+					let keys = Object.keys(family_list);
+					this.family.id = Number(keys[keys.length - 1]) + 1;
+				}
+			}
+		},
+		data() {
+			return {
+				title: '成员资料',
+				button_text: '保存',
+				
+				family:{
+					id: null,
+					name: '',
+					relationship: '',
+					gender: '',
+					age: '',
+				},
+				gender: '',
+				columns: [['男','女']],
+			}
+		},
+		methods: {
+			inputBindBlur(type){
+				this.$content_check.textCheck(this.family[type], this, 'family.' + type);
+			},
+			changegender() {
+				this.$refs.picker.open();
+			},
+			confirm(e) {
+				this.family.gender = e['indexs'][0];
+				this.gender = this.family.gender === 0 ? '男' : '女';
+			},
+			async update(){
+				if(this.family.name.length == 0){
+					console.log("用户名无效");
+					uni.showToast({duration:1500,icon:"none",title: '请输入用户名'});
+					return ;
+				}
+				
+				//用户名必须由1到20个字符组成,并且只能包含字母、数字、汉字。
+				const regex = /^[a-zA-Z0-9\u4e00-\u9fa5]{1,20}$/;
+				const isValid = regex.test(this.family.name);
+				if (!isValid) {
+					console.log("用户名无效");
+					uni.showToast({duration:1500,icon:"none",title: '用户名只能包含字母和数字'});
+					return ;
+				}
+				console.log("用户名有效");
+				
+				let isCheck = await this.$content_check.textCheck(this.family.name, this, 'family.name');
+				console.log('isCheck: ',isCheck);
+				if(isCheck !== true) return ;
+				
+				isCheck = await this.$content_check.textCheck(this.family.relationship, this, 'family.relationship');
+				console.log('isCheck: ',isCheck);
+				if(isCheck !== true) return ;
+				
+				let family_list = uni.getStorageSync('family_list');
+				if(!family_list || Object.keys(family_list).length == 0) family_list = {};
+				
+				family_list[this.family.id] = this.family;
+
+				console.log('family_list: ',family_list);
+				
+				uni.setStorageSync('family_list', family_list);
+				
+				uni.showToast({duration:1000,icon:'success',title: '保存成功 !'});
+				setTimeout(() => uni.navigateBack(), 1300);
+			}
+		}
+	}
+</script>
+
+<style>
+	page {
+		height: 100vh;
+	}
+	.top-back{
+		height: 30px;
+		background-color: #1678ff;
+		color: #fff;
+		margin-bottom: -40px;
+	}
+	
+	.head-text{
+		letter-spacing: 5px;
+		font-weight: 600;
+	}
+	.title{
+		letter-spacing: 2px;
+		color: #8c92ad;
+		font-size: 18px;
+	}
+	input {
+		letter-spacing: 1px;
+	    width: 100%;
+		height: 8vh;
+	    padding-bottom: 5px;
+	    font-size: 24px;
+		font-weight: 600;
+		font-weight: 400;
+		color: #000;
+	    outline: none; /* 移除聚焦时的默认边框 */
+	}
+	.content {
+	  padding: 0 35px;
+	  border-radius: 25px;
+	  border: none;
+	  background-color: #ffffff;
+	}
+	.content image:active {
+		transform: translateY(2px) translateX(2px);
+	}
+
+</style>

+ 14 - 12
chexnet-master-MP/pages/my/my.vue

@@ -21,7 +21,7 @@
 				
 				<uv-divider customStyle="margin:0px;width:92%;margin:0 auto;"></uv-divider>
 				
-				<button class="button-item flex justify-between">
+				<button @click="$util.navigateTo('/pages/my/family/family')" class="button-item flex justify-between">
 					<view class="align-center flex justify-between">
 						<image style="background-color: #fff;" src="@/static/img/family.png"></image>
 						<text>家庭成员</text>
@@ -41,9 +41,9 @@
 				
 				<uv-divider customStyle="margin:0px;width:92%;margin:0 auto;"></uv-divider>
 				
-				<button class="button-item flex justify-between">
+				<button @click="$util.navigateTo('/pages/img_process/img_process_history/img_process_history')" class="button-item flex justify-between">
 					<view class="align-center flex justify-between">
-						<image style="background-color: #fff;" src="@/static/img/medical_box.png"></image>
+						<image style="background-color: #fff;" src="@/static/img/识别.png"></image>
 						<text>病例识别记录</text>
 					</view>
 					<text class="cuIcon-right"></text>
@@ -51,23 +51,24 @@
 				
 				<uv-divider customStyle="margin:0px;width:92%;margin:0 auto;"></uv-divider>
 				
-				<button @click="$util.navigateTo('/pages/BMI/BMI_history/BMI_history')" class="button-item flex justify-between">
+				<button @click="$util.navigateTo('/pages/health_tip/health_tip_collect/health_tip_collect')" class="button-item flex justify-between">
 					<view class="align-center flex justify-between">
-						<image style="background-color: #fff;" src="@/static/img/bmi.png"></image>
-						<text>BMI 记录</text>
+						<image style="background-color: #fff;" src="@/static/img/health-tip.png"></image>
+						<text>健康知识收藏夹</text>
 					</view>
 					<text class="cuIcon-right"></text>
 				</button>
 				
 				<uv-divider customStyle="margin:0px;width:92%;margin:0 auto;"></uv-divider>
 				
-				<button class="button-item flex justify-between">
+				<button @click="$util.navigateTo('/pages/BMI/BMI_history/BMI_history')" class="button-item flex justify-between">
 					<view class="align-center flex justify-between">
-						<image style="background-color: #fff;" src="@/static/img/health-tip.png"></image>
-						<text>健康知识收藏夹</text>
+						<image style="background-color: #fff;" src="@/static/img/bmi.png"></image>
+						<text>BMI 记录</text>
 					</view>
 					<text class="cuIcon-right"></text>
 				</button>
+				
 			</view>
 			
 			<view class="button-group">
@@ -91,7 +92,7 @@
 				
 				<uv-divider customStyle="margin:0px;width:92%;margin:0 auto;"></uv-divider>
 				
-				<button class="button-item flex justify-between">
+				<button @click="$util.navigateTo('/pages/my/setting/setting')" class="button-item flex justify-between">
 					<view class="align-center flex justify-between">
 						<text style="margin:0 12px 0 3px;font-size: 25px;" class="cuIcon-settings"></text>
 						<text>设置</text>
@@ -109,11 +110,12 @@
 
 <script>
 	export default {
-		onLoad() {
+		onShow() {
 			this.name = uni.getStorageSync("name");
 		},
 		onPullDownRefresh(){
-			
+			this.name = uni.getStorageSync("name");
+			setTimeout(() => {uni.stopPullDownRefresh();}, 1000);
 		},
 		data() {
 			return {

+ 81 - 0
chexnet-master-MP/pages/my/setting/setting.vue

@@ -0,0 +1,81 @@
+<template>
+	<view>
+		<view class="button-group">
+			<button @click="radioChange">
+				<view class="align-center flex justify-between">
+					<image style="background-color: #ffffff;" :src="doctor_gender == 1 ? doctor_woman : doctor_man"></image>
+					<text>主页医生</text>
+				</view>
+				<radio-group class="center">
+					<label class="margin-right-sm"><radio class="margin-right-xs" value="r1" :checked="doctor_gender == 0" />男</label>
+					<label><radio class="margin-right-xs" value="r2" :checked="doctor_gender == 1" />女</label>
+				</radio-group>
+			</button>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		onLoad() {
+			let doctor_gender = uni.getStorageSync('doctor_gender');
+			if(doctor_gender === 0) this.doctor_gender = 0;
+			else this.doctor_gender = 1;
+		},
+		data() {
+			return {
+				doctor_woman: '/static/img/女医生.png',
+				doctor_man: '/static/img/男医生.png',
+				doctor_gender: 1
+			}
+		},
+		methods: {
+			radioChange() {
+				if(this.doctor_gender === 1) this.doctor_gender = 0;
+				else this.doctor_gender = 1;
+				uni.removeStorageSync('doctor_gender');
+				uni.setStorageSync('doctor_gender',this.doctor_gender);
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	page{
+		background-color: #f5f5f5;
+	}
+	text{
+		font-size: 18px;
+		display: flex;
+		justify-content: center; /* 水平居中 */
+		align-items: center;    /* 垂直居中 */
+	}
+	image{
+		margin-right: 10px;
+		width: 30px;
+		height: 30px;
+		background-color: #ffffff;
+	}
+	.button-group{
+		border: none;
+		width: 100%;
+		background-color: #ffffff;
+		margin-bottom: 15px;
+		border-radius: 0px;
+		
+		button{
+			border: 1px;
+			border-color: #000;
+			border-radius: 0px;
+			height: 12vw;
+			padding: 0 10px;
+			background-color: #ffffff;
+			display: flex;
+			justify-content: space-between;
+		}
+		button:active {
+			filter: brightness(80%);
+			opacity: 0.8;
+		}
+	}
+</style>

+ 20 - 8
chexnet-master-MP/pages/my/user_info/user_info.vue

@@ -15,7 +15,9 @@
 					<uv-gap height="10" ></uv-gap>
 					
 					<view class="flex justify-between">
-						<input maxlength=20 class="" type="nickname" style="width: 60%;" v-model="user.name" placeholder-style="color: #cccccc; font-size: 24px; font-weight: 100;" placeholder="请输入昵称" />
+						<input maxlength=20 class="" type="nickname" style="width: 60%;" v-model="user.name" 
+							placeholder-style="color: #cccccc; font-size: 24px; font-weight: 100;" placeholder="请输入昵称" 
+						/>
 						<image src="@/static/img/user.png" style="background-color: #fff;width: 15vw;height: 15vw;margin: 0 30px 5px;"></image>
 					</view>
 				</view>
@@ -42,7 +44,7 @@
 				<view class="" style="margin-bottom: -20upx;"><!-- 年龄 -->
 					<view class="title">年龄</view>
 					<uv-gap height="10" ></uv-gap>
-					<input class="weui-input" type="number" v-model="user.age" placeholder-style="color: #cccccc; font-size: 24px; font-weight: 100;" placeholder="请输入年龄" />
+					<input maxlength=3 class="weui-input" type="number" v-model="user.age" placeholder-style="color: #cccccc; font-size: 24px; font-weight: 100;" placeholder="请输入年龄" />
 				</view>
 				<uv-divider customStyle="margin: 0 0"></uv-divider>
 				
@@ -89,7 +91,10 @@
 				request: 1,
 			}
 		},
-		methods: {	
+		methods: {
+			// inputBindBlur(){
+			// 	this.$content_check.textCheck(this.user.name, this, 'user.name');
+			// },
 			changegender() {
 				this.$refs.picker.open();
 			},
@@ -97,9 +102,9 @@
 				this.user.gender = e['indexs'][0];
 				this.gender = this.user.gender === 0 ? '男' : '女';
 			},
-			update(){
+			async update(){
 				if(this.user.name.length > 0){
-					//用户名必须由1到20个字符组成,并且只能包含字母和数字。
+					//用户名必须由1到20个字符组成,并且只能包含字母、数字、汉字。
 					const regex = /^[a-zA-Z0-9\u4e00-\u9fa5]{1,20}$/;
 					const isValid = regex.test(this.user.name);
 					
@@ -110,15 +115,22 @@
 							let user = uni.getStorageSync("user");
 							
 							if(!this.$util.ObjectEqual(user,this.user)){
+								
+								let isCheck = await this.$content_check.textCheck(this.user.name, this, 'user.name');
+								console.log('isCheck: ',isCheck);
+								if(isCheck !== true) return ;
+								
 								this.request = 0;
+								
 								uni.showLoading({title: '加载中...'});
 								console.log('this.user: ',this.user);
 								this.$user_api.user_update(this.$util.removeNullValues(this.user))
 									.then((res) => {
+										uni.setStorageSync("name",this.user.name);
+										uni.setStorageSync("user",this.user);
 										this.request = 1;
 										uni.hideLoading();
 										uni.showToast({duration:1000,icon:'success',title: '保存成功 !'});
-										
 									}).catch((err) => {  
 										this.request = 1;
 										uni.hideLoading();
@@ -148,10 +160,10 @@
 		height: 100vh;
 	}
 	.top-back{
-		height: 25px;
+		height: 30px;
 		background-color: #1678ff;
 		color: #fff;
-		margin-bottom: -5vh;
+		margin-bottom: -40px;
 	}
 	.top-back p{
 		height: 7.5vh;

+ 0 - 184
chexnet-master-MP/style/animation.css

@@ -1,184 +0,0 @@
-/* 
-  Animation 微动画  
-  基于ColorUI组建库的动画模块 by 文晓港 2019年3月26日19:52:28
- */
-
-/* css 滤镜 控制黑白底色gif的 */
-.gif-black{  
-  mix-blend-mode: screen;  
-}
-.gif-white{  
-  mix-blend-mode: multiply; 
-}
-
-
-/* Animation css */
-[class*=animation-] {
-    animation-duration: .5s;
-    animation-timing-function: ease-out;
-    animation-fill-mode: both
-}
-
-.animation-fade {
-    animation-name: fade;
-    animation-duration: .8s;
-    animation-timing-function: linear
-}
-
-.animation-scale-up {
-    animation-name: scale-up
-}
-
-.animation-scale-down {
-    animation-name: scale-down
-}
-
-.animation-slide-top {
-    animation-name: slide-top
-}
-
-.animation-slide-bottom {
-    animation-name: slide-bottom
-}
-
-.animation-slide-left {
-    animation-name: slide-left
-}
-
-.animation-slide-right {
-    animation-name: slide-right
-}
-
-.animation-shake {
-    animation-name: shake
-}
-
-.animation-reverse {
-    animation-direction: reverse
-}
-
-@keyframes fade {
-    0% {
-        opacity: 0
-    }
-
-    100% {
-        opacity: 1
-    }
-}
-
-@keyframes scale-up {
-    0% {
-        opacity: 0;
-        transform: scale(.2)
-    }
-
-    100% {
-        opacity: 1;
-        transform: scale(1)
-    }
-}
-
-@keyframes scale-down {
-    0% {
-        opacity: 0;
-        transform: scale(1.8)
-    }
-
-    100% {
-        opacity: 1;
-        transform: scale(1)
-    }
-}
-
-@keyframes slide-top {
-    0% {
-        opacity: 0;
-        transform: translateY(-100%)
-    }
-
-    100% {
-        opacity: 1;
-        transform: translateY(0)
-    }
-}
-
-@keyframes slide-bottom {
-    0% {
-        opacity: 0;
-        transform: translateY(100%)
-    }
-
-    100% {
-        opacity: 1;
-        transform: translateY(0)
-    }
-}
-
-@keyframes shake {
-
-    0%,
-    100% {
-        transform: translateX(0)
-    }
-
-    10% {
-        transform: translateX(-9px)
-    }
-
-    20% {
-        transform: translateX(8px)
-    }
-
-    30% {
-        transform: translateX(-7px)
-    }
-
-    40% {
-        transform: translateX(6px)
-    }
-
-    50% {
-        transform: translateX(-5px)
-    }
-
-    60% {
-        transform: translateX(4px)
-    }
-
-    70% {
-        transform: translateX(-3px)
-    }
-
-    80% {
-        transform: translateX(2px)
-    }
-
-    90% {
-        transform: translateX(-1px)
-    }
-}
-
-@keyframes slide-left {
-    0% {
-        opacity: 0;
-        transform: translateX(-100%)
-    }
-
-    100% {
-        opacity: 1;
-        transform: translateX(0)
-    }
-}
-
-@keyframes slide-right {
-    0% {
-        opacity: 0;
-        transform: translateX(100%)
-    }
-
-    100% {
-        opacity: 1;
-        transform: translateX(0)
-    }
-}

+ 0 - 3721
chexnet-master-MP/style/base.css

@@ -1,3721 +0,0 @@
-/* page{
-	background-color: #f6f6f6;
-	color: #333333;
-} */
-.text-decoration{
-	text-decoration:line-through;
-}
-.text-vip-style{
-	color: #fbbd08;
-	text-shadow: 0px 0upx 1px rgba(0, 0, 0, 0.3);
-}
-.header{
-	position: fixed;
-	z-index: 999;
-	left: 0px;
-	width: 100%;
-	transition:0.3s all;
-}
-.header .cu-bar{
-	/*  #ifdef APP-PLUS || H5  */
-	/* box-shadow: 0px 0px 8upx rgba(0, 0, 0, 0.1); */
-	/*  #endif  */
-	
-}
-.header .content{
-	color: #333;
-}
-.header .action{
-	color: #333;
-}
-.swiper-text{
-	position: absolute;
-	top: 0upx;
-	
-	width: 100%;
-	height: 100%;
-	color: #fff;
-	padding: 0px 60upx;
-	background-color: rgba(0,0,0,0.25);
-}
-.swiper-title{
-	font-size: 40upx;
-	padding-top: 120upx;
-	font-weight: bold;
-	margin-bottom: 15upx;
-	opacity: 0.9;
-	text-overflow: -o-ellipsis-lastline;
-	overflow: hidden;
-	text-overflow: ellipsis;
-	display: -webkit-box;
-	-webkit-line-clamp: 1;
-	line-clamp: 1;
-	-webkit-box-orient: vertical;
-}
-.swiper-intro{
-	opacity: 0.6;
-	text-overflow: -o-ellipsis-lastline;
-	overflow: hidden;
-	text-overflow: ellipsis;
-	display: -webkit-box;
-	-webkit-line-clamp: 1;
-	line-clamp: 1;
-	-webkit-box-orient: vertical;
-}
-.toGroup{
-	padding: 2upx 10upx;
-	font-size: 24upx;
-	border: solid 1px #333;
-	border-radius: 5upx;
-	color: #333;
-}
-.index-sort{
-	background-color: #fff;
-	text-align: center;
-	padding: 0px 15upx;
-	/* box-shadow: 0px 0px 5px rgba(0,0,0,.1); */
-}
-.index-sort-main{
-	padding: 25upx 0upx;
-}
-.index-sort-i{
-	width: 80upx;
-	height: 80upx;
-	line-height: 80upx;
-	text-align: center;
-	margin: 0 auto 10upx auto;
-	color: #fff;
-	background-color: #0081ff;
-	font-size: 36upx;
-	border-radius: 50%;
-	/* box-shadow: 1px 2px 2px rgba(0,0,0,.15); */
-	opacity: 0.8;
-}
-.tool-sort .index-sort-i{
-	width: 90upx;
-	height: 90upx;
-	line-height: 90upx;
-}
-.inbox-sort{
-	padding: 20upx 0px;
-}
-.inbox-sort .index-sort-i{
-	width: 90upx;
-	height: 90upx;
-	line-height: 90upx;
-	position: relative;
-}
-.inbox-sort .index-sort-i .unreadNum{
-	position: absolute;
-	top:-16upx;
-	right: -16upx;
-	font-size: 24upx;
-	line-height: 34upx;
-	display: block;
-	text-align: center;
-	padding: 0 10upx;
-	height: 34upx;
-	border-radius: 50%;
-}
-.index-sort-text{
-	font-size: 26upx;
-}
-.index-sort .index-sort-box:nth-child(1) .index-sort-i{
-	background-color: #fbbd08;
-	
-}
-.index-sort .index-sort-box:nth-child(2) .index-sort-i{
-	background-color: #39b54a;
-}
-.index-sort .index-sort-box:nth-child(3) .index-sort-i{
-	background-color: #2eabbf; 
-}
-.index-sort .index-sort-box:nth-child(4) .index-sort-i{
-	background-color: #e54d42;
-}
-.index-sort .index-sort-box:nth-child(5) .index-sort-i{
-	background-color: #24c597;
-}
-.index-sort .index-sort-box:nth-child(6) .index-sort-i{
-	background-color: #e03997;
-}
-.index-sort .index-sort-box:nth-child(7) .index-sort-i{
-	background-color: #eb550f;
-}
-.index-sort .index-sort-box:nth-child(8) .index-sort-i{
-	background-color: #4343e7;
-}
-.index-sort .index-sort-box:nth-child(9) .index-sort-i{
-	background-color: #ff9f10;
-}
-.data-box{
-	margin-top: 12upx;
-	background-color: #ffffff;
-	/* box-shadow: 0px 0px 5px rgba(0,0,0,.1); */
-	padding: 0upx;
-}
-.all-box{
-	margin-top: 20upx;
-	background-color: #ffffff;
-}
-.data-box-title{
-	color: #333;
-	font-size: 30upx !important;
-	font-weight: bold;
-	
-	text-overflow: -o-ellipsis-lastline;
-	overflow: hidden;
-	text-overflow: ellipsis;
-	display: -webkit-box;
-	-webkit-line-clamp: 2;
-	line-clamp: 2;
-	-webkit-box-orient: vertical;
-}
-.more text{
-	font-size: 24upx;
-	color: #999;
-}
-.more .cuIcon-right{
-	font-size: 30upx !important;
-	color: #999;
-}
-.data-box .cu-bar{
-	border:none;
-	min-height: 80upx;
-}
-.data-time{
-	background: none !important;
-	color: #999 !important;
-	float: right;
-	padding: 0;
-}
-.text-i{
-	height: auto;
-	overflow: hidden;
-}
-.data-author{
-	background: none !important;
-	padding-left: 0px !important;
-	color: #999;
-}
-.data-author .cuIcon-message{
-	margin-right: 10upx;
-	font-size: 28upx;
-}
-.data-author text{
-	margin-right: 6upx;
-}
-.data-box .cu-item{
-	padding-top: 30upx;
-	border-bottom: solid 1px #f9f9f9;
-	
-}
-.data-box .cu-item .cu-item.category-item{
-	border-bottom:none;
-	padding-top: 0upx;
-	padding:20upx 0upx;
-	background:#f3f3f3;
-	margin-top: 18upx;
-	border-radius: 8upx;
-}
-.cu-card.article{
-	border-bottom: solid 1px #f3f3f3;
-}
-.user .data-box .cu-item{
-	border-bottom: none;
-}
-.cu-list.menu-avatar>.cu-item.userinfo:after{
-	border-bottom: none;
-}
-.data-box .cu-card .desc .text-content{
-	font-size: 32upx !important;
-	color: #333 !important;
-	height: auto !important;
-	overflow: hidden;
-	text-overflow: ellipsis;
-	display:-webkit-box;
-	-webkit-box-orient:vertical;
-	-webkit-line-clamp:2;
-}
-.cu-card.article>.cu-item .content .text-content{
-	overflow: hidden;
-	text-overflow: ellipsis;
-	display:-webkit-box;
-	-webkit-box-orient:vertical;
-	-webkit-line-clamp:3;
-	word-break: break-all;
-}
-.cu-card.article>.cu-item .content.article-content .text-content{
-	-webkit-line-clamp:2;
-	height: 2.8em;
-	overflow: hidden;
-}
-.cu-card.article>.cu-item .content.article-content {
-	display: block;
-}
-.cu-card.article>.cu-item .content.article-content>image{
-	float: left;
-	height: 5.5em;
-}
-.cu-card.article>.cu-item  .article-content-btn{
-	padding: 0px 30upx;
-	margin-top: 20upx;
-}
-.content-author{
-	line-height: 45upx;
-	height: 45upx;
-	overflow: hidden;
-	margin-top: 25upx;
-	font-size: 24upx;
-	color: #666;
-}
-.content-author.bigImg-style{
-	margin-top: 15upx;
-	margin-bottom: 0upx;
-}
-.article-imgMain{
-	padding: 0upx 20upx;
-}
-.cu-card.article>.cu-item .article-content-btn.article-list-btn{
-	margin-top: 10upx;
-}
-.article-img{
-	padding: 0upx 10upx;;
-}
-.article-img image{
-	width: 100%;
-	height: 150upx;
-	border-radius:8upx;
-	background-color: #f3f3f3;
-}
-.content-author image{
-	width: 45upx;
-	display: block;
-	float: left;
-	height: 45upx;
-	margin-right: 15upx;
-	border-radius: 50%;
-}
-.cu-card.article>.cu-item .title{
-	line-height: 70upx;
-	margin-top: 15upx;
-	margin-bottom: 5upx;
-}
-.content-author .article-category{
-	float: right;
-}
-.content-author.content-header{
-	padding: 0upx 30upx;
-}
-.data-box  .cu-card.article>.cu-item .content>image{
-	width: 220upx;
-	height: 6em;
-	
-	border-radius: 15upx;
-}
-.text-rule{
-	color: #0081FF;
-	display: none;
-}
-.topic{
-	padding: 0upx 15upx;
-	width: 100%;
-}
-.topic-box{
-	padding:10upx;
-}
-.topic-main{
-	border-radius: 15upx;
-	overflow: hidden;
-	
-	height: 160upx;
-	position: relative;
-}
-.topic-main image{
-	width: 100%;
-	height: 160upx;
-	transition:0.3s all;
-}
-.topic-main:hover image{
-	-webkit-transform:scale(1.3);
-	-ms-transform:scale(1.3);
-	transform:scale(1.3);
-}
-.topic-text{
-	position: absolute;
-	width: 100%;
-	height: 160upx;
-	text-align: center;
-	line-height: 160upx;
-	top: 0px;
-	font-size: 30upx;
-	left: 0px;
-	font-weight: bold;
-	z-index: 10;
-	background-color: rgba(0,0,0,0.25);
-	color: #fff;
-}
-.news-box{
-	padding: 30upx;
-	color: #333;
-	font-size: 32upx;
-	border-bottom: solid 1px #f9f9f9;
-	text-overflow: -o-ellipsis-lastline;
-	overflow: hidden;
-	text-overflow: ellipsis;
-	display: -webkit-box;
-	-webkit-line-clamp: 1;
-	line-clamp: 1;
-	-webkit-box-orient: vertical;
-}
-.info{
-	
-}
-.info-title{
-	padding: 40upx 30upx 20upx 30upx;
-	font-size: 36upx;
-	line-height: 60upx;
-	font-weight: bold;
-	background: #fff;
-	
-}
-.info-tyle{
-	padding: 0upx 30upx 20upx 30upx;
-	font-size: 24upx;
-	background: #fff;
-	border-bottom: solid 1px #f3f3f3;
-}
-.info-tyle .cuIcon-attention{
-	margin: 0upx 8upx 0upx 20upx;
-}
-.info-date{
-	float: right;
-	color: #999;
-}
-.info-content{
-	background: #fff;
-	font-size: 30upx;
-	line-height:1.8;
-	padding: 10upx 30upx 40upx 30upx;
-}
-.user-form{
-	margin-top: 100upx;
-	padding: 0upx 80upx;
-}
-.user-form .cu-form-group{
-	margin-bottom: 20upx;
-	border: solid #f3f3f3 1px;
-	min-height: 90upx;
-	border-radius: 10upx;
-}
-.user-form .user-btn{
-	margin-top: 60upx;
-}
-.user-foget{
-	width: 100%;
-	height: 90upx;
-	line-height: 90upx;
-	color: #999;
-	text-align: center;
-	position: fixed;
-	bottom: 50upx;
-	left: 0px;
-}
-.metaList{
-	padding: 0px 10upx;
-}
-.home-nav.metaList{
-	position: fixed;
-	left: 0px;
-	width: 100%;
-	z-index:300;
-	background-color: #fff;
-}
-.goCategory{
-	height: 80upx;
-	width: 60upx;
-	line-height: 80upx;
-	height: 80upx;
-	position: absolute;
-	font-weight: bold;
-	text-align: center;
-	right: 10upx;
-	top: 0;
-	font-size: 36upx;
-}
-.home-nav.metaList .nav {
-	width: calc(100% - 60upx);
-}
-.home-nav.metaList .nav .cu-item{
-	height: 80upx;
-	line-height: 80upx;
-	padding: 0upx 12upx;
-}
-.metaList .nav .cu-item.cur{
-	border:none;
-	color: #000;
-	border-bottom: #0081ff 4upx solid;
-	/* font-size: 32upx; */
-	font-weight: bold;
-}
-.nav.forumTop .cu-item{
-	height: 90upx;
-	line-height: 90upx;
-	padding: 0upx 12upx;
-}
-.nav.forumTop .cu-item.cur{
-	border:none;
-	color: #000;
-	border-bottom: #0081ff 4upx solid;
-	/* font-size: 32upx; */
-	font-weight: bold;
-}
-.load-more{
-	background-color: #f3f3f3;
-	height: 80upx;
-	line-height: 80upx;
-	text-align: center;
-}
-.userList .cuIcon-lightfill{
-	margin-left: 10upx;
-	background-color: #fbbd08;
-	color: #333333;
-	display: inline-block;
-	height: 40upx;
-	width: 40upx;
-	text-align: center;
-	border-radius: 50%;
-	font-size: 24upx;
-	
-}
-
-.no-data{
-	width: 100%;
-	padding: 60upx 0upx;
-	text-align: center;
-	color: #999;
-	font-size: 26upx;
-}
-.no-data .cuIcon-text{
-	display: block;
-	font-size: 80upx;
-	color: #ddd;
-	margin-bottom: 15upx;
-}
-.content image{
-	background-color: #f3f3f3;
-}
-.top{
-	padding: 0upx 30upx 20upx 30upx;
-}
-.top-box{
-	padding: 20upx 0upx;
-	border-bottom: solid 1px #f9f9f9;
-	overflow:hidden;
-	text-overflow:ellipsis;
-	white-space:nowrap;
-}
-.top-box text{
-	display: inline-block;
-	width: 35upx;
-	height: 35upx;
-	background-color: #8799a3;
-	text-align: center;
-	line-height: 35upx;
-	color: #fff;
-	margin-right: 15upx;
-	border-radius: 50%;
-	margin-left: 10upx;
-}
-.top-box:nth-child(1) text{
-	background-color:#fbbd08;
-	box-shadow: 0px 0px 8upx #fbbd08;
-	color: #333;
-}
-.top-box:nth-child(2) text{
-	background-color:#e54d42;
-	box-shadow: 0px 0px 8upx #e54d42;
-}
-.top-box:nth-child(3) text{
-	background-color:#f37b1d;
-	box-shadow: 0px 0px 8upx #f37b1d;
-}
-.category{
-	padding: 15upx;
-}
-.category-box{
-	padding: 10upx;
-}
-.category-content{
-	padding-bottom: 20upx;
-	/* border-left:  solid 1px #f3f3f3;
-	border-right:  solid 1px #f3f3f3; */
-}
-.category-main{
-	padding: 18upx;
-	text-align: center;
-	/* color: #0081ff;
-	border: solid 1px rgba(0, 129, 255, 0.4); */
-	color: #000;
-	/* border: solid 1px #ccc; */
-	background-color: #f3f3f3;
-	border-radius: 8upx;
-}
-.category-box.active .category-main{
-	color: #fff;
-	border: solid 1px #0081ff;
-	background-color:  #0081ff;
-	box-shadow: 0upx 0upx 15upx #0081ff;
-	
-}
-.allCategory{
-	margin-top: 5upx;
-}
-.category-item{
-	padding: 0upx 20upx;
-	background: #fff;
-	margin-bottom: 10upx;
-	border-radius: 8upx;
-}
-.category-item-title{
-	height: 90upx;
-	line-height: 90upx;
-}
-.category-item-title text{
-	float: right;
-}
-.category-manage-sub{
-	padding: 10upx 30upx;
-}
-.tags{
-	width: 100%;
-	overflow: hidden;
-	padding: 20upx;
-}
-.tags text.tags-box{
-	padding:12upx 25upx;
-	line-height: 40upx;
-	text-align: center;
-	color: #0081ff;
-	border: none;
-	background-color: rgba(0, 129, 255, 0.2);
-	width: auto;
-	margin: 10upx;
-	border-radius: 30upx;
-	float: left;
-	font-size: 24upx;
-	opacity: 0.9;
-}
-.tags text.tags-box.active{
-	color: #fff;
-	border: solid 1px #0081ff;
-	background-color:  #0081ff;
-	box-shadow: 0upx 0upx 15upx #0081ff;
-}
-.info-content .tags{
-	padding: 0upx;
-	border-top: solid 1px #f9f9f9;
-	padding-top: 30upx;
-}
-.data-box .menu .cu-item{
-	padding-top: 0upx;
-}
-.edit-tool{
-	height: 80upx;
-	line-height: 80upx;
-	padding: 0upx 10upx;
-}
-.edit-tool text{
-	display: inline-block;
-	margin: 0upx 10upx;
-	width: 40upx;
-	font-size: 40upx;
-}
-.edit-tool text.cuIcon-read{
-	float: right;
-}
-.cu-form-group .text{
-	/* height: calc(100vh - 490upx); */
-	/* #ifdef APP-PLUS */
-	/* height: calc(100vh - 540upx); */
-	/* #endif */
-	line-height: 45upx;
-	width: 100%;
-}
-.cu-form-group scroll-view.text{
-	padding: 30upx 0upx;
-}
-.LinksModal input{
-	height: 70upx;
-	text-align: left;
-	padding: 10upx 20upx;
-	font-size: 24upx;
-	border: solid #999 1px;
-	border-radius: 8upx;
-	background-color: #fff;
-}
-.LinksModal input:nth-child(1){
-	margin-bottom: 30upx;
-}
-.post{
-	max-height: 100%;
-}
-.update-tips{
-	padding: 6upx;
-	border-radius: 4upx;
-	font-size: 22upx;
-	margin-right: 10upx;
-}
-.logout{
-	width: 100%;
-	margin-top: 30upx;
-	padding: 0upx 30upx;
-}
-.logout-main{
-	width: 100%;
-	text-align: center;
-	border-radius: 10upx;
-	height: 80upx;
-	line-height: 80upx;
-	background-color: #fff;
-}
-.ImageList{
-	width: 100%;
-	padding: 0upx 20upx;
-}
-
-.ImageList-box{
-	height: 500upx;
-	overflow: hidden;
-	margin-bottom: 20upx;
-	border-radius: 20upx;
-	position: relative;
-}
-.setImage{
-	position: absolute;
-	right: 10px;
-	top: 10px;
-	z-index: 150;
-	border-radius: 5px;
-}
-.image-info{
-	position: absolute;
-	bottom: 30upx;
-	left: 0upx;
-	padding: 0upx 30upx;
-}
-.image-info text{
-	padding: 10upx;
-	background-color: #008080;
-	color: #fff;
-	font-size: 24upx;
-	opacity: 0.8;
-	border-radius: 8upx;
-}
-.ImageList image{
-	width: 100% !important;
-}
-.comment{
-	position: relative;
-}
-.copy-comment{
-	opacity: 0;
-	position: absolute;
-	right: 30upx;
-	top: 0upx;
-	z-index: 888;
-	color: #0081FF;;
-	font-size: 22upx;
-	padding: 5upx 20upx;
-	border-radius: 8upx;
-	border: solid 1px #0081FF;;
-	background-color: #e0eaff;;
-	transition:0.3s all;
-	-webkit-transition:0.3s all;
-	-moz-transition:0.3s all;
-	-o-transition:0.3s all;
-	-ms-transition:0.3s all;
-}
-.cu-list.comment:hover .copy-comment{
-	opacity: 1;
-}
-.search-type{
-	line-height: 80upx;
-	padding: 0upx 30upx;
-	text-align: center;
-	height: 80upx;
-	border-bottom: solid 1px #f3f3f3;
-	position: relative;
-	z-index: 10;
-}
-.search-type-box{
-	color: #999;
-}
-.search-type-box.active{
-	border-bottom: solid 2px #0081FF;
-	color: #333;
-}
-.loading{
-	width: 100%;
-	height: 100vh;
-	z-index: 888;
-	background-color: #fff;
-	position: fixed;
-	top: 0;
-	left: 0;
-	text-align: center;
-}
-.loading-main{
-	position: fixed;
-	width: 100%;
-	top: 40%;
-}
-.loading image{
-	width: 100upx;
-	height: 100upx;
-}
-.menu-avatar{
-	position: relative;
-	width: 100%;
-}
-.clock-btn{
-	position: absolute;
-	top: 50upx;
-	right: 40upx;
-	border-radius: 8upx;
-	font-size: 24upx;
-	color: #fff;
-	padding: 10upx 25upx;
-	background-color: #1AAD16;
-}
-.clock-btn.istap{
-	background-color: #008080;
-}
-.user-data{
-	padding: 30upx 30upx 10upx 30upx;
-	text-align: center;
-	border-top: solid 1px #f3f3f3;
-	margin-top: 20upx;
-}
-.user-data-box{
-	height: 88upx;
-}
-.user-data-title{
-	font-size: 24upx;
-	color: #999;
-	margin-top: 10upx;
-}
-.user-data-value{
-	color: #2eabbf;
-	font-size: 40upx;
-}
-.user-data-box:nth-child(1){
-	border-right: solid 1px #f6f6f6;
-}
-.user-data-box:nth-child(2){
-	border-right: solid 1px #f6f6f6;
-}
-.user-data-box:nth-child(3) .user-data-value{
-	color: #fbbd08;
-}
-.usermarks .data-box{
-	background: none;
-}
-.usermarks .data-box .cu-item{
-	padding-top: 0px !important;
-	margin-bottom: 10upx;
-	border: none;
-}
-.usermarks .cu-list.menu-avatar>.cu-item:after,.usermarks  .cu-list.menu>.cu-item:after{
-	border: none;
-}
-.usermarks .cu-avatar.lg{
-	width: 80upx;
-	height: 80upx;
-}
-.usermarks .cu-list.menu-avatar>.cu-item .content{
-	left: 130upx;
-}
-.cu-card.article>.cu-item .content>image{
-	width: 220upx;
-}
-.info-btn .cuIcon-favor,.info-btn .cuIcon-favorfill{
-	margin-right: 5upx;
-}
-.info-btn .cuIcon-favorfill{
-	color: #fbbd08;
-}
-.content-btn{
-	max-width: 400upx;
-	margin: 0 auto;
-	padding: 40upx 0upx;
-	text-align: center;
-}
-.content-btn-i{
-	border-radius: 10upx;
-	margin: 0 auto;
-}
-.content-btn-i text{
-	color: #999;
-	font-size: 24upx;
-}
-.content-btn-i .btn-i{
-	display: block;
-	color: #0081FF;
-	font-size: 60upx;
-	
-}
-.content-btn-i .cuIcon-rechargefill{
-	color: #DD514C;
-}
-.api-login{
-	text-align: center;
-	width: 450upx;
-	margin: 50upx auto 0upx auto;
-}
-.api-login-box{
-	text-align: center;
-}
-.api-login-box image{
-	width: 90upx;
-	height: 90upx;
-}
-.all-btn{
-	padding: 0upx 50upx;
-}
-.post-update{
-	position: fixed;
-	bottom: 50upx;
-	right: 30upx;
-	width: 90upx;
-	height: 90upx;
-	color: #fff;
-	text-align: center;
-	line-height: 90upx;
-	border-radius: 50%;
-	box-shadow: 0px 0px 8upx rgba(0, 0, 0, 0.1);
-}
-.manage-data{
-	padding: 10upx 20upx 20upx 20upx;
-}
-.manage-data .user-data-box{
-	border-right: solid 1px #f6f6f6;
-	border-top: solid 1px #f6f6f6;
-	padding: 20upx 0upx;
-	height: auto;
-}
-
-.manage-data .user-data-box .user-data-value{
-	color: #ce292c !important;
-	font-size: 30upx;
-}
-.manage-data .user-data{
-	margin-top: 0upx;
-	border:none;
-	padding: 0upx;
-	border-left: solid 1px #f6f6f6;
-	border-bottom: solid 1px #f6f6f6;
-}
-.manage-data.upcoming .user-data{
-	border: none;
-	padding: 5upx;
-	
-}
-.manage-data.upcoming .user-data .user-data-main{
-	background: #f6f6f6;
-	width: 100%;
-	padding: 20upx 0upx;
-	border-radius: 20upx;
-}
-.manage-data.upcoming{
-	padding: 0upx 10upx 20upx 10upx;
-}
-.manage-data.upcoming .user-data-box .user-data-value{
-	color:#f37b1d !important;
-	font-size: 32upx;
-	font-weight: bold;
-}
-.manage-data.upcoming .user-data-box{
-	border: none;
-	padding: 10upx;
-}
-.manage-dataLoad{
-	text-align: center;
-	padding: 100upx 0upx;
-}
-.manage-dataLoad image{
-	width: 100upx;
-}
-
-
-.ruleApi-Info{
-	text-align: center;
-	padding: 30upx 0upx;
-}
-.ruleApi-title{
-	color: #666;
-	margin-bottom: 15upx;
-}
-.ruleApi-Info .ruleApi-Info-box:nth-child(1){
-	border-right: solid 1px #f6f6f6;
-}
-.ruleApi-name{
-	font-size: 45upx;
-	color: #111;
-	margin-bottom: 5upx;
-}
-.ruleApi-version{
-	font-size: 22upx;
-	margin-bottom: 30upx;
-}
-.ruleApi-Info .cu-btn{
-	border-radius: 8upx;
-}
-.update{
-	width: 100%;
-	height: 100vh;
-	position: fixed;
-	z-index: 2000;
-	top: 0;
-	left: 0;
-}
-.update-bg{
-	background-color: #000;
-	width: 100%;
-	height: 100vh;
-	position: fixed;
-	z-index: 2001;
-	top: 0;
-	left: 0;
-	opacity: 0.5;
-}
-.update-box{
-	width: 100%;
-	position: absolute;
-	top: 30%;
-	z-index: 2002;
-}
-.update-main{
-	background-color: #fff;
-	width: 550upx;
-	margin: 0 auto;
-	border-radius: 20upx;
-	text-align: center;
-	padding-bottom: 40upx;
-}
-.update-box image{
-	width: 208upx;
-	height: 135upx;
-	margin: -70upx auto 0 auto;
-}
-.update-title{
-	margin-top: 20upx;
-	font-size: 36upx;
-	margin-bottom: 40upx;
-	font-weight: bold;
-}
-.update-intro{
-	padding: 0upx 40upx 30upx 40upx;
-	font-size: 26upx;
-	text-align: left;
-	line-height: 40upx;
-	color: #666;
-}
-.update-btn{
-	padding: 20upx;
-}
-.update-btn-box{
-	padding: 0upx 20upx;
-}
-.update-btn-main{
-	padding: 15upx 0upx;
-	border-radius: 10upx;
-}
-.pay-codeImg{
-	background-color: #fff;
-	text-align: center;
-	padding: 30upx 0upx;
-}
-.shop-list{
-	padding: 30upx 10upx;
-}
-.shop-box{
-	padding: 10upx 0upx;
-	border-bottom: solid 1px #f6f6f6;
-	-webkit-transition:0.3s all;
-	-moz-transition:0.3s all;
-	-o-transition:0.3s all;
-	-ms-transition:0.3s all;
-}
-.shop-main{
-	padding: 15upx;
-	border-radius: 10upx;
-	overflow: hidden;
-	
-}
-.shop-box:hover{
-	background: #f6f6f6;
-}
-.shop-img{
-	height: 220upx;
-	width: 220upx;
-	border-radius: 15upx;
-	background: #f6f6f6;
-	overflow: hidden;
-	float: left;
-}
-.shop-concent{
-	width: calc(100% - 220upx);
-	float: left;
-	box-sizing: border-box;
-	padding-left: 16upx;
-	position: relative;
-}
-.shop-concent .cuIcon-cart{
-	position: absolute;
-	right: 0;
-	font-size: 30upx;
-	color: #666;
-	bottom: 2upx;
-}
-.shop-img image{
-	width: 100%;
-	border-radius: 15upx;
-	background-color: #f3f3f3;
-}
-.shop-title{
-	font-size:30upx;
-	margin-bottom: 6upx;
-	overflow: hidden;
-	height: 76upx;
-	text-overflow: ellipsis;
-	display:-webkit-box;
-	-webkit-box-orient:vertical;
-	-webkit-line-clamp:2;
-}
-.shop-list-value{
-	font-size: 24upx;
-	color: #999;
-}
-.shop-info{
-	padding: 6upx 0upx;
-	line-height: 40upx;
-}
-.shop-price{
-	font-size: 38upx;
-}
-.shop-info .cuIcon-cart{
-	float:right;
-}
-.shop-list-user{
-	font-size: 24upx;
-}
-.shop-list-user .content-author{
-	margin-top: 0upx;
-}
-.shopinfo-img{
-	width: 100%;
-	height: 400upx;
-	overflow: hidden;
-}
-.shopinfo-img image{
-	width: 100%;
-	height: 400upx;
-}
-.shopinfo-title{
-	font-size: 35upx;
-	line-height: 50upx;
-	font-weight: bold;
-	background-color: #fff;
-	padding: 20upx 30upx;
-	border-bottom: solid 1px #f3f3f3;
-}
-.shopinfo-bar{
-	position: fixed;
-	width: 100%;
-	z-index: 999;
-	bottom: 0;
-	left: 0;
-	background-color: #fff;
-	border-top: solid 1px #f3f3f3;
-	height: 100upx;
-	line-height: 100upx;
-	padding: 0upx 30upx;
-}
-.shopinfo-price{
-	font-size: 38upx;
-	color: #CE292C;
-	font-weight: bold;
-}
-.shopinfo-btn{
-	text-align: right;
-}
-.shopinfo-info{
-	text-align: right;
-	padding: 10upx 30upx;
-	background-color: #fff;
-}
-.shopinfo-tips{
-	padding: 10upx 30upx;
-	background-color: #fff;
-	font-size: 24upx;
-}
-.shop-btn{
-	padding: 8upx 0upx;
-	margin: 0upx 10upx;
-}
-.text-tips{
-	line-height: 40upx;
-}
-.order-box{
-	background-color: #fff;
-	border-top: solid 1px #f3f3f3;
-	padding: 30upx;
-}
-.order-info{
-	margin-bottom: 20upx;
-	line-height: 50upx;
-}
-.order-id{
-	font-weight: bold;
-}
-.order-type{
-	float: right;
-	padding: 5upx 15upx;
-	border-radius: 8upx;
-	font-size: 24upx;
-}
-.order-shop{
-	background-color: #f3f3f3;
-	padding: 30upx;
-	margin-bottom: 20upx;
-}
-.order-btn .text-blue{
-	float: right;
-}
-.order-btn .text-green{
-	float: right;
-}
-.order-btn .order-status{
-	float: right;
-}
-.shop-status{
-	font-size: 22upx;
-	padding: 8upx 15upx;
-	position: absolute;
-	top: 10upx;
-	left: 20upx;
-	z-index: 100;
-	opacity: 0.8;
-	border-radius: 8upx;
-}
-.shop-main{
-	position: relative;
-}
-.setShop{
-	width: 100%;
-	height: 100vh;
-	position: fixed;
-	z-index: 9999;
-}
-.setShop-bg{
-	width: 100%;
-	height: 100vh;
-	position: fixed;
-	z-index: 10000;
-	opacity: 0.5;
-	background-color: #000000;
-}
-.setShop-box{
-	width: 100%;
-	height: 100vh;
-	position: fixed;
-	z-index: 10001;
-	top: 10%;
-}
-.setShop-main{
-	margin: 0 auto;
-	background-color: #fff;
-	width: 550upx;
-	border-radius: 10upx;
-	padding: 30upx;
-}
-.setShop-title{
-	text-align: center;
-	margin-bottom: 30upx;
-	position: relative;
-}
-.setShop-list{
-	background-color: #f3f3f3;
-	height: 670upx;
-	padding: 0upx 10upx;
-}
-.setShop-close{
-	position: absolute;
-	right: -10upx;
-	top: -15upx;
-	font-size: 38upx;
-	font-weight: bold;
-	color: #CE292C;
-}
-.setShop-list-box{
-	width: 100%;
-	padding: 20upx 15upx;
-	background-color: #fff;
-	border-bottom: #ccc;
-	font-size: 24upx;
-	margin: 10upx auto;
-	
-	opacity: 0.8;
-	line-height: 40upx;
-}
-.setShop-list-box text{
-	margin-right: 10upx;
-}
-.setShop-status{
-	text-align: right;
-}
-.setShop-list-box:hover,.setShop-list-box.cur{
-	background-color: #ccc;
-}
-.content-shop .cu-card{
-	/* box-shadow: 0upx 0upx 18upx rgba(0,0,0,0.2); */
-	border: solid 1px #ddd;
-	border-radius: 10upx;
-	overflow: auto;
-}
-.content-shop  .shop-name{
-	padding: 10upx 20upx;
-}
-.shop-tool{
-	padding: 40upx 20px;
-	position: relative;
-}
-.shop-tool .text-content{
-	font-weight: bold;
-	font-size: 30upx;
-	margin-bottom:5upx;
-}
-.shop-tool .cu-btn{
-	border-radius: 5upx;
-	margin: 10upx 10upx 0upx 10upx;
-}
-.shop-tool .tool-price{
-	font-size: 30upx;
-}
-.shop-tool .shop-name{
-	position: absolute;
-	color: #999;
-	top: 0upx;
-	right: 0upx;
-	text-align: right;
-}
-.shop-tool image{
-	width: 180upx;
-	border-radius: 10upx;
-	height: 180upx;
-	margin: 0upx auto;
-	background-color: #F3F3F3;
-}
-.content-shop .cu-card.article>.cu-item .content .text-content{
-	color: #000;
-	font-weight: bold;
-}
-.content-shop .cu-card.article>.cu-item .content .text-red{
-	font-size: 32upx;
-	font-weight: bold;
-}
-.content-shop .cu-card.article>.cu-item .content .cuIcon-cart{
-	float: right;
-}
-.order-time{
-	font-size: 24upx;
-	text-align: right;
-	margin-top: 10upx;
-	color: #ccc;
-}
-.manage-btn{
-	margin-top: 15upx;
-	padding: 0upx 30upx;
-}
-.manage-btn text{
-	margin-right: 20upx;
-}
-.comment-delete{
-	position: absolute;
-	right: 30upx;
-	top: 15upx;
-}
-.comment-audit{
-	position: absolute;
-	right: 180upx;
-	top: 15upx;
-}
-.comment-audit.editorStyle{
-	right: 30upx;
-}
-.myAssets{
-	width: 100%;
-	text-align: center;
-	padding: 50upx 30upx;
-	
-}
-.myAssets .myAssets-box:nth-child(2){
-	border-left: solid 1px #f3f3f3;
-}
-.myAssets-num{
-	font-size: 55upx;
-	margin-right: 10upx;
-}
-.myAssets-btn{
-	text-align: center;
-	padding-bottom: 30upx;
-}
-.myAssets-btn text{
-	margin: 0upx 20upx;
-}
-.userrecharge{
-	padding: 30upx;
-}
-.userrecharge-type{
-	margin-bottom: 40upx;
-}
-.userrecharge-type text{
-	margin-right: 10upx;
-}
-.userrecharge-type text.active{
-	color: #fff !important;
-	background-color: #0081FF;
-}
-.userrecharge-code{
-	text-align: center;
-	margin-bottom: 40upx;
-}
-.userrecharge-code image{
-	border: 30upx solid #aecfff;
-	border-radius: 20upx;
-	width: 400upx;
-	height: 400upx;
-}
-.userrecharge-btn{
-	text-align: center;
-	margin-bottom: 20upx;
-}
-.userrecharge-btn text{
-	margin:0upx 20upx;
-}
-.userrecharge-intro-title{
-	font-size: 35upx;
-	font-weight: bold;
-	margin-top: 50upx;
-}
-.userrecharge-intro{
-	line-height: 45upx;
-	margin-top: 30upx;
-}
-.userrecharge-intro-text{
-	margin-top: 20upx;
-	font-size: 26upx;
-}
-.userrecharge-form{
-	padding: 30upx 30upx;
-	text-align: center;
-	
-}
-
-.userrecharge-form input{
-	border: solid #ccc 1px;
-	height: 70upx;
-	line-height: 70upx;
-	margin-bottom: 40upx;
-	padding: 20upx;
-}
-.userrecharge-form.toEpay{
-	position: relative;
-}
-.userrecharge-form.toEpay input{
-	padding-left: 200upx;
-}
-.toEpayType{
-	position: absolute;
-	top: 30upx;
-	left: 30upx;
-	
-}
-.toEpayType-cur{
-	height: 70upx;
-	line-height: 70upx;
-	text-align: center;
-	width: 200upx;
-}
-.toEpayType-main{
-	position: relative;
-	z-index: 20;;
-	margin-top: 10upx;
-	width: 250upx;
-	padding: 10upx 20upx;
-	overflow: hidden;
-	border-radius: 10upx;
-	background-color: #fff;
-	box-shadow: 0upx 0upx 10upx rgba(0,0,0,0.2);
-}
-.toEpayType-main>view{
-	height: 60upx;
-	line-height: 60upx;
-	text-align: center;
-	padding: 0px 15upx;
-}
-.pay-status{
-	float: right;
-}
-.cur-assets{
-	padding: 0upx 30upx;
-}
-.cur-assets text{
-	font-weight: bold;
-	font-size: 35upx;
-}
-.userwithdraw-box{
-	background-color: #fff;
-	padding:10upx 30upx 30upx 30upx;
-}
-.order-kill{
-	margin-top: 30upx;
-}
-.order-kill text{
-	margin-left: 15upx;
-}
-.index-sort-main.active{
-	background-color: #f3f3f3;
-}
-.content-shop .cu-card{
-	position: relative !important;
-}
-.info-shop-status{
-	position: absolute;
-	top: 20upx;
-	left: 30upx;
-	z-index: 100;
-	opacity: 0.7;
-}
-.shop-content{
-	padding-bottom: 100upx !important;
-}
-.comments-owo{
-	padding: 10upx 30upx;
-	width: 100%;
-	position: relative;
-	
-}
-.comments-owo .cuIcon-emoji{
-	font-size: 50upx;
-}
-.owo{
-	width: 550upx;
-	height: 320upx;
-	background-color: #fff;
-	position: absolute;
-	z-index: 200;
-	left: 30upx;
-	top: 80upx;
-	box-shadow: 0upx 0upx 20upx rgba(0,0,0,0.4);
-	overflow: hidden;
-	border-radius: 20upx;
-}
-.owo-list{
-	width: 100%;
-	height: 220upx;
-	width: 100%;
-}
-.owo-type{
-	width: 100%;
-	margin-top: 30upx;
-	height: 70upx;
-	font-size: 26upx;
-	border-top: solid 1px #ddd;
-}
-.owo-box{
-	line-height: 70upx;
-	padding: 0upx 30upx;
-	float: left;
-}
-.owo-box.cur{
-	background: #eee;
-}
-.owo-main{
-	padding: 20upx;
-	overflow: hidden;
-}
-.owo-lit-box{
-	width: 70upx;
-	text-align: center;
-	height: 70upx;
-	float: left;
-}
-.owo-lit-box image{
-	width: 50upx;
-	height: 50upx;
-}
-.text-content{
-	vertical-align:middle;
-}
-.tImg{
-	width: 40upx;
-	height: 40upx;
-	
-}
-.OwO-box{
-	display: inline-block;
-	position: relative;
-}
-.info-footer{
-	position: fixed;
-	z-index: 200;
-	bottom: 0;
-	left: 0;
-	width: 100%;
-	height:100upx;
-	background-color: #fff;
-	border-top: #eee solid 1px;
-	box-sizing: content-box;
-}
-.info-footer-input{
-	padding: 15upx 30upx;
-}
-.info-input-box{
-	height: 70upx;
-	border-radius: 15upx;
-	background-color: #f1f1f1;
-	text-align: center;
-	font-size: 24upx;
-	line-height: 70upx;
-	color: #666;
-}
-.info-input-box text{
-	margin-right: 15upx;
-}
-.info-footer-btn{
-	padding-right: 20upx;
-	font-size: 50upx;
-	line-height: 100upx;
-}
-.info-footer-btn text{
-	margin: 0upx 20upx;
-}
-
-.info-operate-bg{
-	position: fixed;
-	background-color: #000;
-	width: 100%;
-	height: 100vh;
-	opacity: 0;
-	z-index: 170;
-	left: 0px;
-	top: 0px;
-	transition: 0.2s all;
-	visibility:hidden;
-}
-.info-operate-bg.show{
-	opacity: 0.3;
-	visibility:visible;
-}
-.info-operate{
-	position: fixed;
-	z-index: 180;
-	bottom:-200upx;
-	left: 0;
-	width: 100%;
-	padding: 0upx 30upx;
-	transition: 0.2s all;
-}
-.info-operate.show{
-	bottom:120upx;
-}
-.info-operate-main{
-	width: 100%;
-	height: 200upx;
-	border-radius: 40upx;
-	padding-top: 18upx;
-	background: #fff;
-	box-shadow: 0px 0px 10upx rgba(0, 0, 0, 0.2);
-	overflow: hidden;
-	text-align: center;
-}
-
-.user-list-btn{
-	width: 340upx !important;
-}
-.user-list-btn .cu-btn{
-	margin-right: 20upx;
-	margin-top: 0upx !important;
-	float: right;
-}
-.agreement{
-	padding: 0upx 30upx 30upx 30upx;
-	background-color: #fff;
-	font-size: 30upx;
-	line-height: 50upx;
-	height: 100vh;
-}
-.agreement-title{
-	font-size: 35upx;
-	font-weight: bold;
-	margin-top: 20upx;
-}
-.agreement-text{
-	margin-top: 15upx;
-}
-.bind image{
-	border-radius: 50%;
-}
-.shop-operate{
-	position: relative;
-	z-index: 50;
-}
-.shop-sort{
-	width: 100%;
-	overflow: hidden;
-	padding: 20upx;
-	background: #fff;
-}
-.shop-sort.shop-filter{
-	overflow: initial;
-	position: relative;
-}
-.shop-type{
-	border-top: #eee solid 1px;
-}
-
-.shop-sort .shop-sort-box{
-	padding:10upx 30upx;
-	line-height: 40upx;
-	text-align: center;
-	width: auto;
-	margin: 10upx 10upx 10upx 0upx;
-	border-radius: 30upx;
-	float: left;
-	font-size: 24upx;
-	color: #666;
-	background-color: #eee;
-	border:solid 1px #eee;
-	opacity: 0.9;
-}
-.shop-sort .shop-sort-box.active{
-	background-color: #e9f2ff;
-	border-color: #0081FF;
-	color: #0081FF;
-}
-.shop-sort-list{
-	position: absolute;
-	z-index: 100;
-	background: #fff;
-	min-height: 180upx;
-	left: 0;
-	width: 100%;
-	padding: 20upx 20upx 0upx 20upx;
-	border-bottom-right-radius: 20upx;
-	border-bottom-left-radius: 20upx;
-	overflow: hidden;
-}
-.shop-sort-list-box{
-	line-height: 80upx;
-	height: 80upx;
-}
-.shop-sort-list-box+.shop-sort-list-box {
-    border-top: 0.5px solid #f6f6f6;
-}
-.shop-sort-list-bg{
-	position: fixed;
-	z-index: -20;
-	width: 100%;
-	height: 100vh;
-	top: 0;
-	left: 0;
-	background: #000;
-	opacity: 0.4;
-}
-.shop-admin-info{
-	width: 100%;
-	float: left;
-	margin-top: 20upx;
-}
-.shop-user{
-	float: left;
-}
-.break-all{
-	word-break: break-all;
-}
-.user-info,.section-info{
-	height: 450upx;
-	width: 100%;
-	overflow: hidden;
-	position: relative;
-}
-.user-info-bg,.section-info-bg{
-	position: absolute;
-	height: 450upx;
-	/* #ifdef APP-PLUS || MP */
-	height: 450upx;
-	/* #endif */
-	top:0;
-	left: 0;
-	filter: blur(20upx);
-	width: 100%;
-	z-index: 0;
-	transform: scale(1.2);
-	
-}
-.user-info-bg.infoBg-Show{
-	filter: blur(0upx);
-}
-.section-info-bg{
-	/* #ifdef APP-PLUS || MP */
-	height: 500upx;
-	/* #endif */
-}
-.section-info-bg{
-	filter:none;
-}
-.user-info-bg image{
-	width: 100%;
-}
-.section-info-bg image{
-	width: 100%;
-}
-.user-info-main,.section-info-main{
-	position: absolute;
-	top: 0;
-	left: 0;
-	height: 450upx;
-	/* #ifdef APP-PLUS || MP */
-	height: 450upx;
-	/* #endif */
-	
-	width: 100%;
-	z-index: 5;
-	background-color: rgba(0,0,0,0.2);
-}
-.section-info-main{
-	/* #ifdef APP-PLUS || MP */
-	height: 450upx;
-	/* #endif */
-}
-.user-info-content,.section-info-content{
-	width: 100%;
-	padding: 0upx 60upx 30upx 60upx;
-	position: absolute;
-	bottom: 0;
-	left: 0;
-	
-	background: linear-gradient(to bottom, rgba(6, 6, 8, 0), rgba(6, 6, 8, 0.7));
-}
-.user-info-col{
-	width: 100%;
-	overflow: hidden;
-	margin-bottom: 30upx;
-}
-.user-info-content .user-header{
-	width: 120upx;
-	text-align: center;
-	float: left;
-}
-.user-header image{
-	width: 120upx;
-	height: 120upx;
-	border-radius: 50%;
-}
-.user-info-content .user-text{
-	width: calc(100% - 120upx);
-	padding-left: 20upx;
-	padding-top: 0upx;
-	font-size: 28upx;
-	color: #fff;
-	float: left;
-	font-weight: bold;
-}
-.user-info-local{
-	font-size: 24upx;
-	opacity: 0.4;
-	font-weight: normal;
-}
-.user-introduce{
-	font-size: 24upx;
-	color: #fff;
-	margin-top: 20upx;
-	overflow: hidden;
-	text-overflow: ellipsis;
-	display: -webkit-box;
-	-webkit-box-orient: vertical;
-	-webkit-line-clamp: 1;
-	word-break: break-all;
-}
-.user-introduce text{
-	margin-right: 10upx;
-	
-}
-.user-edit-header{
-	width: 100%;
-	background-color: #fff;
-	text-align: center;
-	padding-top: 40upx;
-	border-bottom:0.5px solid #eee;
-	padding-bottom: 30upx;
-}
-.user-info-data{
-	margin: 4upx 0px;
-	font-weight: normal;
-}
-.user-data-num{
-	font-weight: bold;
-	margin-right: 10upx;
-}
-.user-data-label{
-	opacity: 0.8;
-}
-.user-info-data-box{
-	margin-right: 20upx;
-}
-.user-info-name{
-	font-size: 36upx;
-}
-.user-edit-header image{
-	width: 150upx;
-	height: 150upx;
-	display: block;
-	border:solid #ddd 1px;
-	margin: 0upx auto 30upx auto;
-	background-color: #f3f3f3;
-	border-radius: 50%;
-}
-.toClub{
-	background-color: #fbbd08 !important;
-	color: #333333 !important;
-}
-.ads-banner{
-	width: 100%;
-	overflow: hidden;
-}
-.ads-banner image{
-	width: 100%;
-	display: block;
-}
-.foreverblog-text{
-	background-color: #f3f3f3;
-	color: #666;
-}
-.foreverblog-text view{
-	word-break: break-all;
-}
-.foreverblog-ico{
-	margin-left: 10upx;
-	font-size: 38upx !important;
-	color: #0081FF;
-}
-.foreverblog-title{
-	color: #333;
-	font-size: 30upx;
-}
-.userlv{
-	font-size: 22upx;
-	background-color: #cecece;
-	line-height: 25upx;
-	padding: 4upx 10upx;
-	border-radius: 8upx;
-	margin-left: 10upx;
-	margin-top: -4upx;
-}
-.identifyLv{
-	font-size: 22upx;
-	line-height: 25upx;
-	padding: 4upx 10upx;
-	border-radius: 8upx;
-	margin-left: 10upx;
-	margin-top: -4upx;
-}
-.cu-avatar{
-	position: relative;
-	overflow: hidden;
-}
-.curLv{
-	padding: 0upx;
-	font-size: 22upx;
-	font-weight: bold;
-	font-style: italic;
-	opacity: 0.7;
-	display: block;
-	width: 100%;
-	position: absolute;
-	bottom: 0;
-	line-height: 30upx;
-	height: 30upx;
-}
-.userlv.customize{
-	background-color: #ba21a8;
-	color: #fff;
-}
-.userlv.bg-red {
-    background-color: #e54d42;
-    color: #ffffff;
-}
-.userinfo-lv{
-	padding-top: 10upx;
-}
-.scan-user{
-	padding-top: 350upx;
-}
-.scan-user image{
-	width: 160upx;
-	border-radius: 50%;
-	height: 160upx;
-	margin-bottom: 20upx;
-}
-.scan-user-name{
-	font-size: 34upx;
-	font-weight: bold;
-	margin-bottom: 20upx;
-}
-.scan-user-btn{
-	margin-top: 100upx;
-}
-.scan-user-btn .cu-btn{
-	height: 90upx;
-	border-radius: 8upx;
-	width: 400upx;
-	margin-bottom: 20px;
-}
-.uni-swiper-slides uni-swiper-item{
-	padding: 15upx 25upx;
-	box-sizing: border-box;
-}
-.uni-swiper-slides .swiper-box{
-	overflow: hidden;
-	width: 100%;
-	position: relative;
-	height: 100%;
-	box-sizing: border-box;
-	border-radius:30upx;
-}
-.screen-swiper{
-	background-color: #fff;
-}
-.vip-maim{
-	padding: 15upx 30upx;
-}
-.vip-maim>view{
-	padding: 40upx 10upx;
-	border-radius: 20upx;
-}
-.vip-maim>view text{
-	font-size:35upx;
-	margin-left: 10upx;
-}
-.isVIP{
-	font-size: 24upx;
-	line-height: 25upx;
-	padding: 4upx 15upx;
-	border-radius: 8upx;
-	margin-left: 10upx;
-	margin-top: -4upx;
-}
-.fullpost-btn{
-	padding: 15upx;
-}
-.fullpost-btn .cu-btn{
-	margin: 10upx;
-	border-radius: 6upx;
-}
-.post-link-type{
-	margin-top: 10upx;
-}
-.post-link-box{
-	padding: 10upx;
-	color: #666;
-}
-.post-link-box.cur{
-	color: #0081FF;
-}
-.tokenList-box{
-	padding: 30upx;
-	border-bottom: solid 1px #f3f3f3;
-	position: relative;
-}
-.tokenList-box .tokenList-info{
-	color: #666;
-	overflow: hidden;
-	margin-top: 15upx;
-}
-.tokenList-box .tokenList-info .cu-btn{
-	position: absolute;
-	right: 30upx;
-	top: 38upx;
-	border-radius: 8upx;
-}
-.shop-value-title{
-	padding-left: 20upx;
-	font-size: 30upx;
-	font-weight: bold;
-	color: #333;
-	line-height: 1;
-	border-left: 8upx solid #0081FF;
-}
-.meta-id{
-	float: right;
-	color: #666;
-	font-size: 26upx;
-}
-.meta-main{
-	line-height: 40upx;
-}
-.setShop-btn{
-	height: 60upx;
-	margin-top: 20upx;
-}
-.Startupmap{
-	width: 100%;
-	height: 100vh;
-	z-index: 10000000;
-	background-color: #fff;
-	position: fixed;
-	top: 0;
-	left: 0;
-}
-.Startupmap-pic{
-	width: 100%;
-	height: 100vh;
-	z-index: 1;
-	background-color: #fff;
-	position: fixed;
-	top: 0;
-	left: 0;
-}
-.Startupmap-pic image{
-	width: 100%;
-	height: 100vh;
-}
-.Startupmap-close{
-	position: fixed;
-	width: 110upx;
-	border-radius: 10upx;
-	font-size: 24upx;
-	height: 50upx;
-	line-height: 50upx;
-	background: rgba(0, 0, 0, 0.4);
-	text-align: center;
-	color: #fff;
-	top: 30upx;
-	right: 30upx;
-	z-index: 2;
-	/* #ifdef APP-PLUS */
-	top: 80upx;
-	/* #endif */
-}
-.article-big{
-	width: 100%;
-}
-.article-big image{
-	width: 100%;
-	height: 350upx;
-	border-radius:8upx;
-	background-color: #f3f3f3;
-}
-.topContents .title{
-	font-weight: bold;
-}
-.topContents .title text{
-	margin-right: 10upx;
-}
-.dataLoad{
-	width: 100%;
-	height: 500upx;
-	text-align: center;
-}
-.dataLoad image{
-	width: 100upx;
-	height: 100upx;
-	margin-top: 200upx;
-}
-.ads-list{
-	padding-top: 10upx;
-}
-.ads-box{
-	background-color: #fff;
-	padding: 10upx 30upx;
-	margin-top: 15upx;
-}
-.ads-name{
-	height: 80upx;
-	line-height: 80upx;
-	font-size: 34upx;
-	border-bottom: solid 1px #f6f6f6;
-	font-weight: bold;
-}
-.ads-text{
-	padding:20upx 10upx;
-	font-size: 26upx;
-	line-height: 50upx;
-	color: #4a4a4a;
-}
-.ads-info{
-	border-top: solid 1px #f6f6f6;
-	line-height: 80upx;
-}
-.ads-price text{
-	font-size: 34upx;
-	font-weight: bold;
-}
-.form-tips{
-	padding: 10upx 30upx;
-}
-.form-tips text{
-	margin-right: 10upx;
-}
-.myAds-box{
-	padding: 28upx 30upx;
-	border-bottom: solid 1px #f6f6f6;
-}
-.myAds-title{
-	font-size: 32upx;
-	font-weight: bold;
-	padding-bottom: 20upx;
-}
-.myAds-concent{
-	height: auto;
-	overflow: hidden;
-	margin-top: 10upx;
-}
-.myAds-time{
-	font-size: 24upx;
-	color: #666;
-}
-.myAds-time .text-green{
-	float: right;
-}
-.myAds-pic{
-	width: 220upx;
-	height: 150upx;
-	overflow: hidden;
-	border-radius: 6upx;
-	float: left;
-	margin-right: 15upx;
-}
-.myAds-pic image{
-	width: 100%;
-	height: 150upx;
-}
-.myAds-intro{
-	text-overflow: -o-ellipsis-lastline;
-	overflow: hidden;
-	text-overflow: ellipsis;
-	display: -webkit-box;
-	-webkit-line-clamp: 4;
-	line-clamp: 4;
-	-webkit-box-orient: vertical;
-}
-.myAds-btn{
-	margin-top: 15upx;
-}
-.myAds-btn text{
-	margin-right:25upx;
-}
-.ads-renewal input{
-	background-color: #fff;
-	border:solid 1px #ddd;
-	height: 80upx;
-}
-.ads-ico{
-	position: absolute;
-	top: 10upx;
-	left: 40upx;
-	background-color: rgba(0, 0, 0, 0.5);
-	display: block;
-	width: 80upx;
-	height: 40upx;
-	border-radius: 8upx;
-	font-size: 24upx;
-	color: #fff;
-	text-align: center;
-	line-height: 40upx;
-}
-.ads-more{
-	margin-top:20upx;
-	font-size:26upx;
-	color:#666;
-	text-align:right;
-}
-.imagetoday-search input{
-	padding-left: 30upx;
-}
-.imagetoday-search .cuIcon-search{
-	font-size: 34upx;
-	margin: 0px;
-	padding: 20px;
-	color: #333;
-}
-.search-close{
-	width: 34upx;
-	overflow: hidden;
-	border-radius: 50%;
-	line-height: 34upx;
-	text-align: center;
-	height: 34upx;
-	margin-right: 20upx;
-	background: #ccc;
-}
-.search-close text{
-	margin: 0 !important;
-	padding: 0;
-}
-.userLoginstatus .cu-dialog{
-	width: 500upx;
-}
-.userLoginstatus-i{
-	width: 80upx;
-	height: 80upx;
-	border-radius: 50%;
-	font-size: 30px;
-	line-height: 80upx;
-	margin: 0 auto 15upx auto;
-}
-.announcement{
-	position: fixed;
-	top: 30%;
-	width: 100%;
-	z-index: 1500;
-}
-.announcement-bg{
-	background-color: #000;
-	opacity: 0.3;
-	position: fixed;
-	width: 100%;
-	top: 0;
-	left: 0;
-	height: 100vh;
-}
-.announcement-main{
-	background-color: #fff;
-	margin: 0 auto;
-	width: 600upx;
-	box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
-	padding: 30upx 36upx;
-	border-radius: 20upx;
-	position: relative;
-	z-index: 10;
-}
-.announcement-title{
-	height: 50upx;
-	line-height: 50upx;
-	font-size: 36upx;
-	font-weight: bold;
-	text-align: center;
-	position: relative;
-}
-.announcement-title text{
-	position: absolute;
-	right: 0;
-}
-.announcement-concent{
-	height:200upx;
-	padding: 20upx;
-	background: #f9f9f9;
-	margin:20upx 0upx;
-	overflow: auto;
-}
-.announcement-btn{
-	text-align: center;
-}
-.meta-type{
-	padding: 5px 12px;
-	border: 2upx solid #0081ff;
-	color: #0081ff;
-	margin-left: 20upx;
-}
-.meta-type.act{
-	background: #0081ff;
-	color: #fff;
-}
-.data-select{
-	text-align: center;
-	margin-top: 20upx;
-}
-.data-select text{
-	color: #666;
-	margin: 0upx 15upx;
-}
-.data-select text.act{
-	color: #000;
-	font-weight: bold;
-}
-.cu-bar .action.header-btn text{
-	font-size: 40upx !important;
-	position: relative;
-}
-.cu-bar .action.header-btn text .noticeSum{
-	position: absolute;
-	opacity: 0.9;
-	font-size: 24upx !important;
-	height: 50upx;
-	width: 50upx;
-	line-height: 50upx;
-	text-align: center;
-	top: -20upx;
-	right: -20upx;
-	border-radius: 50%;
-	transform:scale(0.8);
-	-webkit-transform:scale(0.8);
-}
-.header .search-form{
-	border-radius: 30upx !important;
-}
-.search-form-text{
-	color: #999;
-}
-.cu-avatar .home-noLogin{
-	font-size: 24upx;
-	color: #0081ff;
-}
-.cu-avatar{
-	background-color: #eee;
-}
-.style-title{
-	line-height: 80upx;
-	height: 80upx;
-	padding: 0upx 20upx;
-	color: #333;
-	font-weight: bold;
-	font-size: 28upx;
-	margin-bottom: 20upx;
-}
-.style-concent{
-	text-align: center;
-	padding: 0upx 10upx;
-	padding-bottom: 30upx;
-}
-.style-box{
-	padding: 0upx 10upx;
-}
-.style-i{
-	background: #2196f6;
-	height: 70upx;
-	border-radius: 6upx;
-	line-height: 70upx;
-	font-size: 24upx;
-}
-.style-text{
-	font-size: 24upx;
-	margin-top: 10upx;
-}
-.style-text .cuIcon-check{
-	background: #39b54a;
-	color: #fff;
-	padding: 0px 2upx;
-	border-radius: 50%;
-	margin-right: 5upx;
-}
-.style-concent.style-simple .style-i{
-	border:solid 1px #f3f3f3;
-	background: none;
-	font-weight: bold;
-}
-.userIndex .header{
-	background:none;
-}
-
-.userIndex .header .action{
-	color: #fff;
-}
-.userIndex .header.goScroll{
-	background: #fff
-}
-.userIndex .header.goScroll .action{
-	color: #333;
-}
-.comment-operation{
-	font-size: 24upx;
-	line-height: 20upx;
-	margin-top: 10upx;
-}
-.comment-operation text{
-	margin-right: 20upx;
-}
-.grid.col-6>view {
-    width: 16.666%;
-}
-.user-bantime{
-	font-size: 24upx;
-	margin-left: 10upx;
-}
-.userInfo-bottom-btn{
-	position: fixed;
-	bottom: 0;
-	left: 0;
-	width: 100%;
-	height: 100upx;
-	background: #fff;
-	box-shadow: 0px -4upx 8upx rgba(0,0,0,0.2);
-	text-align: center;
-}
-.userInfo-bottom-box{
-	padding: 0upx 30upx;
-}
-.userInfo-bottom-box button{
-	height:70upx;
-	width: 100%;
-	margin-top: 15upx;
-}
-.userInfo-tochat{
-	height: 100upx;
-	line-height: 100upx;
-	font-size: 30upx;
-}
-.userInfo-tochat text{
-	margin-right: 10upx;
-}
-.userInfo-bottom-box button text{
-	margin-right: 10upx;
-}
-
-.cu-list.menu-avatar>.cu-item .action.goUserIndex{
-	width:180upx;
-}
-.goUserIndex .cu-btn{
-	border-radius: 15upx;
-}
-.goUserIndex .isFollow{
-	background: #0060ba !important;
-	color: #fff !important;
-}
-.goUserIndex .unFollow{
-	background: #0081ff !important;
-	color: #fff !important;
-}
-.goUserIndex .unFollow text{
-	font-weight: bold;
-	margin-right: 5upx;
-}
-.square-box{
-	font-weight: bold;
-	color: #666;
-	margin-right: 15px;
-	font-size: 32upx;
-}
-.square-box.cur{
-	font-size: 38upx;
-	color: #000;
-}
-.square-post{
-	padding: 0 30upx;
-}
-.square-post-header{
-	padding-top: 30upx;
-	overflow: hidden;
-}
-.square-user{
-	width: 80upx;
-	float: left;
-}
-.square-text{
-	width: calc(100% - 80upx);
-	padding: 0px 20upx;
-	float: left;
-	line-height:70upx;
-	box-sizing: border-box;
-	color: #999;
-	border: solid 1px #f3f3f3;
-}
-.square-post-btn{
-	padding: 20upx 0upx;
-}
-.square-post-btn-box{
-	height: 60upx;
-	line-height: 60upx;
-	text-align: center;
-	box-sizing: border-box;
-	border-left: solid 1px #f6f6f6;
-}
-.square-post-btn-box:nth-child(1){
-	border: none;
-}
-.square-post-btn-box text{
-	margin-right: 10upx;
-}
-.cu-list.menu-avatar>.cu-item:after{
-	border: none !important;
-}
-.square-list .cu-item{
-	margin-top: 10upx !important;
-}
-.square-list .cu-avatar.lg{
-	width: 80upx;
-	height: 80upx;
-}
-.square-list .cu-list.menu-avatar>.cu-item .content{
-	left: 130upx;
-}
-.square-post-btn text{
-	margin-right: 10upx;
-	font-size: 35upx;
-}
-.user-post-info{
-	height: 180upx;
-	width: 100%;
-	padding: 20upx;
-	background-color: #f9f9f9;
-	overflow: hidden;
-	border-radius: 10upx;
-}
-.user-post-pic{
-	width: 180upx;
-	height: 140upx;
-	overflow: hidden;
-	border-radius: 8upx;
-	margin-right: 20upx;
-	float: left;
-}
-.user-post-pic image{
-	background-color: #f3f3f3;
-}
-.user-post-title{
-	text-overflow: -o-ellipsis-lastline;
-	overflow: hidden;
-	text-overflow: ellipsis;
-	display: -webkit-box;
-	-webkit-line-clamp: 1;
-	font-size: 30upx;
-	font-weight: bold;
-	margin-top: 8upx;
-	margin-bottom: 18upx;
-	line-clamp: 1;
-	-webkit-box-orient: vertical;
-}
-.user-post-intro{
-	text-overflow: -o-ellipsis-lastline;
-	overflow: hidden;
-	text-overflow: ellipsis;
-	display: -webkit-box;
-	font-size: 26upx;
-	line-height: 36upx;
-	-webkit-line-clamp: 2;
-	line-clamp: 2;
-	-webkit-box-orient: vertical;
-	color: #666666;
-}
-.user-space-info{
-	width: 100%;
-	padding: 20upx;
-	background-color: #f9f9f9;
-	overflow: hidden;
-	border-radius: 10upx;
-	color: #666;
-}
-.user-space-info .user-space-text{
-	text-overflow: -o-ellipsis-lastline;
-	overflow: hidden;
-	text-overflow: ellipsis;
-	display: -webkit-box;
-	-webkit-line-clamp: 3;
-	line-clamp: 3;
-	-webkit-box-orient: vertical;
-}
-.admin-btn{
-	display: none;
-}
-.cu-item:hover .admin-btn{
-	display: inline;
-}
-.data-box.data-inbox .cu-item{
-	padding-top: 0upx;
-}
-.chat-owo.owo{
-	width: 100%;
-	left: 0px;
-	position: fixed;
-	border-radius: 0upx;
-	bottom:100upx;
-	top: auto;
-}
-.cu-chat .main image{
-	background: #f3f3f3;
-}
-.more-msg{
-	height: 90upx;
-	text-align: center;
-	line-height: 90upx;
-}
-.space-info .cu-item{
-	padding-bottom: 30upx;
-}
-.space-reply{
-	background: #fff;
-	margin-top: 20upx;
-}
-.space-reply-head{
-	height: 90upx;
-	line-height: 70upx;
-	padding: 10upx 30upx;
-	font-size: 30upx;
-	border-bottom: solid 2upx #f6f6f6;
-}
-.space-reply-head text{
-	color: #999;
-	font-weight: bold;
-}
-.space-reply-head text.cur{
-	color: #333;
-	border-bottom: solid 4upx #2196f6;
-	padding-bottom: 16upx;
-}
-.space-reply-likes{
-	float: right;
-}
-.space-reply-list .no-data .cu-btn{
-	border-radius: 8upx;
-}
-.space-reply-num{
-	background: #f3f3f3;
-}
-.space-reply-list .comment .cu-item{
-	border-bottom: solid 2upx #f6f6f6;
-}
-.space-footer {
-    position: fixed;
-    bottom: 0;
-    left: 0;
-    width: 100%;
-    height: 100upx;
-	padding: 20upx 0upx;
-	line-height: 60upx;
-    background: #fff;
-	font-size: 30upx;
-    border-top: solid 2upx #f6f6f6;
-    text-align: center;
-}
-.space-footer-box text{
-	margin-right: 10upx;
-}
-.space-footer .space-footer-box:nth-child(2){
-	border-left: solid 2upx #f6f6f6;
-	border-right: solid 2upx #f6f6f6;
-}
-.space-owo{
-	height: 80upx;
-	background-color: #fff;
-}
-.space-owo .cuIcon-emoji{
-	float: right;
-}
-.space-owo .owo{
-	left: auto;
-	right: 30upx;
-}
-.space-pic{
-	padding: 20upx;
-}
-.space-upload{
-	background-color: #e0e0e0;
-}
-.space-upload text{
-	font-size:80upx !important;
-}
-.space-pic .bg-img{
-	position: relative;
-	
-}
-.space-pic .bg-img .cuIcon-close{
-	width:60upx;
-	opacity: 0.8;
-	height:60upx;
-	border-radius: 50%;
-	background: #CE292C;
-	color: #fff !important;
-	font-size: 30upx !important;
-}
-.cu-list.menu-avatar>.cu-item .action.space-follow{
-	width: 180upx;
-	margin-top: -28upx;
-}
-.cu-list.menu-avatar>.cu-item .action.space-follow .cu-btn{
-	border-radius: 10upx;
-	height: 58upx;
-	line-height: 58upx;
-	padding: 0upx 24upx;
-}
-.cu-list.menu-avatar>.cu-item .action.space-follow .cu-btn text{
-	margin-right: 4upx;
-}
-.spaceVideo video{
-	width: 100%;
-	border-radius: 8upx;
-}
-.bg-img{
-	background-color: #f3f3f3;
-}
-.search-space{
-	background-color: #f6f6f6;
-}
-.videoPlay{
-	position: fixed;
-	z-index: 1000;
-	left: 0px;
-	top: 0px;
-	width: 100%;
-	height: 100vh;
-}
-.videoPlay-bg{
-	position: fixed;
-	z-index: 1;
-	left: 0px;
-	top: 0px;
-	width: 100%;
-	background-color: #111;
-	height: 100vh;
-}
-.videoPlay video{
-	position: absolute;
-	height: 500upx;
-	width: 100%;
-	top:50%;
-	margin-top:-250upx;
-}
-.spaceVideo-play{
-	width: 100%;
-	border-radius: 8upx;
-	background-color: #000;
-	font-size: 70upx;
-	color:#fff;
-	text-align: center;
-	height: 400upx;
-	line-height: 400upx;
-}
-.videoPlay-close{
-	position: fixed;
-	top: 80upx;
-	right: 30upx;
-	color: #fff;
-	font-size: 50upx;
-}
-.payinfo-text{
-	margin-bottom: 20upx;
-}
-.payinfo-text-name{
-	margin-right: 20upx;
-}
-.payinfo-text-value{
-	font-size: 30upx;
-	color: #000;
-	font-weight: bold;
-}
-.forumIndex .screen-swiper{
-	margin-top: 10upx;
-	background: none
-}
-.forumIndex .uni-swiper-slides uni-swiper-item {
-    padding: 7px 7px;
-}
-.screen-swiper image{
-	border-radius: 15px;
-}
-.section-box{
-	padding: 6upx 15upx;
-	margin-bottom: 10upx;
-}
-.section-main{
-	background: #fff;
-	border-radius: 8upx;
-	box-shadow: 0px 0px 15upx rgba(0, 0, 0, 0.15);
-}
-.section-box-title{
-	color: #333;
-	font-size: 30upx !important;
-	font-weight: bold;
-	padding:20upx 20upx 0upx 20upx;
-	margin-bottom: 6upx;
-}
-.section-item{
-	overflow: hidden;
-}
-.section-ico{
-	width: 110upx;
-	height: 110upx;
-	overflow: hidden;
-	float: left;
-	margin-right: 10upx;
-	overflow: hidden;
-	padding: 10upx;
-}
-.section-box-list{
-	padding: 10upx;
-}
-.section-ico image{
-	width:100%;
-	height: 100%;
-	border-radius: 20upx;
-}
-.section-item{
-	padding: 10upx;
-	transition: all 0.2s;
-}
-.section-item:hover{
-	background-color: #f6f6f6;
-}
-.section-intro{
-	padding-top: 4upx;
-}
-.section-item-value,.shop-item-value{
-	font-size: 24upx;
-	color: #999;
-	margin-top: 8upx;
-}
-.section-item-title,.shop-item-title{
-	margin-top: 12upx;
-	font-weight: bold;
-	margin-bottom: 6upx;
-}
-.section-info-main{
-	color: #fff;
-}
-.section-info-full{
-	overflow: hidden;
-}
-.section-info-content{
-	padding: 0upx 40upx 30upx 40upx;
-}
-.section-info-ico{
-	width: 140upx;
-	height: 140upx;
-	float: left;
-	margin-right: 20upx;
-}
-.section-info-intro{
-	width: calc(100% - 160upx);
-	float: left;
-}
-.section-info-ico image{
-	width: 100%;
-	height: 100%;
-	border-radius: 20upx;
-}
-.section-info-title{
-	
-	padding-top: 25upx;
-	font-weight: bold;
-	font-size: 32upx;
-	margin-bottom: 15upx;
-}
-.section-info-value{
-	font-size: 24upx;
-	opacity: 0.9;
-}
-.section-info-value text{
-	margin-right: 18upx;
-}
-.section-info-moderator{
-	margin-top: 20upx;
-	margin-bottom: 15upx;
-}
-.moderator-btn{
-	padding: 10upx 35upx;
-	background: rgba(255, 255, 255, 0.3);
-	border-radius: 12upx;
-	font-size: 24upx;
-}
-.moderator-btn text{
-	margin: 0upx 10upx;
-}
-.section-info-clock .cu-btn{
-	float: right;
-	font-size: 26upx;
-	border-radius: 20upx;
-}
-.forum-list{
-	width: 100%;
-	position: relative;
-	z-index: 200;
-	min-height: 300upx;
-	border-top-right-radius: 15upx;
-	border-top-left-radius: 15upx;
-	margin-top: -15upx;
-	overflow: hidden;
-}
-.forum-list-type{
-	padding: 20upx 10upx 10upx 10upx;
-	background-color: #fff;
-}
-.forum-list-type text{
-	padding: 0upx 10upx;
-	margin-right: 20upx;
-	font-size: 30upx;
-	font-weight: bold;
-	color: #818181;
-}
-.forum-list-type text.act{
-	color: #000;
-	font-size: 38upx;
-}
-.forum-list-top{
-	background: #fff;
-	padding:0upx 10upx 10upx 10upx;
-}
-.forum-top-box{
-	padding: 15upx 10upx;
-	line-height: 44upx;
-	overflow: hidden;
-}
-.forum-top-i{
-	width: 80upx;
-	float: left;
-	font-weight: bold;
-}
-.forum-top-text{
-	width: calc(100% - 80upx);
-	float: left;
-	font-weight: bold;
-	font-size: 30upx;
-	color: #000;
-	overflow:hidden; 
-	text-overflow:ellipsis;
-	white-space:nowrap;
-}
-.forum-list-main{
-	margin-top: 7.5upx;
-}
-.forum-list-box{
-	padding: 7.5upx 0upx;
-}
-.postReview .forum-list-box{
-	border-bottom: solid 1px #f6f6f6;
-}
-.forum-list-content{
-	background: #fff;
-	padding:20upx 20upx;
-	box-sizing: border-box;
-}
-.forum-list-user{
-	width: 100%;
-	overflow: hidden;
-	margin-bottom: 16upx;
-}
-.forum-avatar{
-	width: 90upx;
-	height: 90upx;
-	float: left;
-	margin-right: 12upx;
-}
-.forum-avatar image{
-	width: 100%;
-	height: 100%;
-	border-radius: 20upx;
-}
-.forum-userinfo{
-	width: calc(100% - 102upx);
-	font-size: 26upx;
-	margin-top: 8upx;
-	position: relative;
-	float: left;
-}
-.forum-follow-btn{
-	position: absolute;
-	right: 0;
-	top: 0upx;
-	border-radius: 8upx;
-}
-.forum-userinfo-name{
-	color: #000;
-	font-weight: bold;
-}
-.forum-userinfo-date{
-	font-size: 24upx;
-	margin-top: 6upx;
-	color: #999;
-}
-.forum-list-text{
-	font-size: 30upx;
-	line-height: 46upx;
-	margin-bottom:10upx;
-}
-.forum-list-title{
-	color: #000;
-	font-weight: bold;
-	margin-bottom: 12upx;
-	font-size: 32upx;
-}
-.forum-list-intro{
-	font-size: 28upx;
-	color: #666;
-	text-overflow: -o-ellipsis-lastline;
-	overflow: hidden;
-	text-overflow: ellipsis;
-	display: -webkit-box;
-	-webkit-line-clamp: 3;
-	line-clamp: 3;
-	-webkit-box-orient: vertical;
-}
-.forum-media image{
-	border-radius: 10upx;
-}
-.forum-one{
-	width: 80%;
-	border-radius: 10upx;
-	height: auto;
-	overflow: hidden;
-	max-height: 500upx;
-}
-.section-sub{
-	line-height: 50upx;
-	height: 60upx;
-	padding: 5upx 30upx;
-	font-size: 26upx;
-	border-radius: 20upx;
-}
-.section-sub image{
-	width: 50upx;
-	height: 50upx;
-	margin-right: 10upx;
-	border-radius: 50%;
-	background-color: #0081ff;
-	padding: 0upx;
-}
-.forum-author{
-	padding: 10upx 20upx;
-	background: #fff;
-	position: relative;
-}
-.forum-follow{
-	position: absolute;
-	right: 20upx;
-	border-radius: 10upx;
-	top: 4upx;
-}
-.forum-comment-type text{
-	margin-left: 20upx;
-	color: #999;
-}
-.forum-comment-type text.act{
-	color: #000;
-	font-weight: bold;
-}
-.section-page,.shop-page{
-	width: 100%;
-	overflow: hidden;
-	padding-bottom: 10upx;
-}
-.section-page-box,.shop-page-box{
-	width: 100%;
-	overflow: hidden;
-	padding: 10upx 20upx;
-	position: relative;
-}
-.section-page-btn,.shop-page-btn{
-	position: absolute;
-	top: 30upx;
-	right: 20upx;
-}
-.section-page-btn .cu-btn,.shop-page-btn .cu-btn{
-	border-radius: 10upx;
-}
-.section-ico-no{
-	width: 100%;
-	height: 100%;
-	text-align: center;
-	line-height: 100upx;
-	border-radius: 10upx;
-	font-size: 40upx;
-	background: #36accf;
-	color: #fff;
-}
-.section-ico-no.bg-pink {
-    background-color: #e03997;
-    color: #ffffff;
-}
-.section-ico-no.bg-purple{
-	background-color: #6739b6;
-	color: #ffffff;
-}
-.forum-post-btn{
-	position: fixed;
-	z-index: 888;
-	bottom: 30upx;
-	right: 20upx;
-	width: 90upx;
-	height: 90upx;
-	font-size: 40upx;
-	color: #fff;
-	background: #0081ff;
-	border-radius: 50%;
-	box-shadow: 0upx 0upx 10upx rgba(0,0,0,0.9);
-	text-align: center;
-	line-height: 90upx;
-}
-.section-info-main .section-ico-no{
-	height: 120upx;
-	margin: 10upx 0upx 0upx 0upx;
-	width: 120upx;
-	line-height: 120upx;
-	font-size: 50upx;
-	border-radius: 10upx;
-}
-.reward-log{
-	width: 100%;
-	overflow: auto;
-	padding: 15upx 20upx;
-	background: #fff;
-	border-top: #f9f9f9 solid 1px;
-}
-.reward-log-main{
-	width: calc(100% - 60upx);
-	float: left;
-}
-.reward-log-btn{
-	width: 60upx;
-	float: left;
-}
-.reward-log-box{
-	width: 90upx;
-	text-align: center;
-	float: left;
-}
-.reward-log-box .reward-log-i{
-	width: 70upx;
-	height: 70upx;
-	background: #f3f3f3;
-	line-height: 70upx;
-	text-align: center;
-	border-radius: 50%;
-	font-size: 40upx;
-	margin: 0 auto 10upx auto;
-}
-.reward-log-box .reward-log-i image{
-	width: 70upx;
-	height: 70upx;
-}
-.reward-log-box .reward-log-value{
-	font-size: 24upx;
-}
-.reward-log-box.reward-total .reward-log-i{
-	background: #ff6b6b;
-	color: #fff;
-}
-.reward-log-btn{
-	text-align: center;
-	font-size: 40upx;
-	line-height: 100upx;
-}
-.reward-log-box .reward-log-i image{
-	border-radius: 50%;
-}
-.forum-swiper{
-	position: absolute;
-	bottom: 0upx;
-	padding: 30upx 30upx 50upx 30upx;
-	font-size: 30upx;
-	left: 15upx;
-	width: calc(100% - 30upx);
-	z-index: 20;
-	border-bottom-right-radius: 30upx;
-	border-bottom-left-radius: 30upx;
-	overflow: hidden;
-	bottom: 15upx;
-	color: #fff;
-}
-.forum-swiper-title{
-	position: relative;
-	z-index: 5;
-}
-.forumIndex uni-swiper .uni-swiper-dots-horizontal{
-	bottom: 30upx !important;
-}
-.forumIndex .uni-swiper-dot.uni-swiper-dot-active{
-	background: #fff !important;
-}
-.forumIndex .uni-swiper-dot.uni-swiper-dot-active::after{
-	background-color: #fff !important;
-}
-.forumIndex .forum-swiper-bg{
-	width: 100%;
-	height: 100%;
-	position: absolute;
-	bottom: 0;
-	left: 0;
-	z-index: 0;
-	background: linear-gradient(to bottom, rgba(6, 6, 8, 0), rgba(6, 6, 8, 0.7));
-}
-.cu-card.space-info>.cu-item>.text-content,.cu-card.square-list>.cu-item>.text-content{
-	max-height: unset !important;
-}
-.full-noLogin{
-	width: 100%;
-	height: 100vh;
-	z-index: 899;
-	background-color: #fff;
-	position: fixed;
-	top: 0;
-	left: 0;
-	text-align: center;
-}
-.full-noLogin-main{
-	position: fixed;
-	width: 100%;
-	top: 35%;
-}
-.full-noLogin-text{
-	font-size: 32upx;
-	margin-bottom: 30upx;
-	font-weight: bold;
-	color: #000;
-}
-.full-noLogin-btn .cu-btn{
-	border-radius: 10upx;
-}
-
-.app-about{
-	text-align: center;
-	margin-top: 80upx;
-	margin-bottom: 50upx;
-	padding:30upx;
-}
-.app-logo image{
-	width: 160upx;
-	border-radius: 30%;
-	border: solid 1px #f3f3f3;
-}
-.app-name{
-	font-size: 40upx;
-	margin-top: 16upx;
-	font-weight: bold;
-}
-.about-tips{
-	font-size:24upx;
-	padding: 30upx;
-	line-height: 36upx;
-	opacity: 0.7;
-}
-.app-ver{
-	font-size:24upx;
-	opacity: 0.8;
-}
-.cu-dialog.kaptcha-dialog{
-	background: #fff;
-}
-.kaptcha-form{
-	padding: 30upx 60upx 60upx 60upx;
-}
-.kaptcha-input{
-	border: solid 1px #0081ff;
-	box-sizing: border-box;
-	overflow: hidden;
-	border-radius: 8upx;
-	margin-top: 20upx;
-}
-.kaptcha-input input{
-	width: calc(100% - 120upx);
-	float: left;
-	height: 70upx;
-}
-.kaptcha-input .cu-btn{
-	width: 120upx;
-	height: 70upx;
-	float: left;
-}
-.shop-item-intro{
-	padding-left: 10upx;
-}
-.tabbarActive{
-	color: #0081FF !important;
-}
-.tabbar view{
-	overflow: initial;
-	display: block;
-}
-.tabbar{
-	position: fixed;
-	bottom: 0;
-	left: 0;
-	right: 0;
-	z-index: 990;
-	overflow: initial;
-	display: block;
-	width: 100%;
-	height:100upx;
-	background-color: #ffffff;
-	border-top: solid 1px #f6f6f6;
-	box-sizing:content-box;
-}
-.tabbar-item{
-	display: block;
-	height: 100upx;
-	float: left;
-	background: #fff;
-	width: calc(25% - 32upx);
-	text-align: center;
-	overflow: hidden;
-	border: none;
-	margin: 0;
-	padding: 0;
-	box-sizing: border-box;
-}
-.tabbar-item .item-img{
-	width: 46upx;
-	height: 46upx;
-	display: block;
-	margin: 0 auto;
-	margin-top: 10upx;
-	text-align: center;
-}
-.tabbar-item .item-name{
-	font-size: 24upx;
-	margin-top: 4upx;
-	color: #333;
-}
-.tabbar-item.addPost{
-	width: 120upx;
-	height: 120upx;
-	padding: 0;
-	position: relative;
-	overflow: initial;
-	box-sizing: border-box;
-	background-color: #fff;
-}
-.tabbar-item.addPost .addPost-main{
-	position: absolute;
-	top: -30upx;
-	background-color: #fff;
-	width: 100%;
-	height: 100%;
-	border-radius: 50%;
-	border: solid 1px #f9f9f9;
-	position: relative;
-	padding: 10upx;
-	box-sizing: border-box;
-}
-.addPost-i{
-	background-color: #0081FF;
-	width: 100%;
-	height: 100%;;
-	border-radius: 50%;
-	line-height: 100upx;
-	text-align: center;
-	font-size: 70upx;
-	color: #fff;
-	font-weight: bold;
-	transition: all 0.3s;
-}
-.postShow .addPost-i{
-	transform: rotate(135deg) translateZ(0);
-}
-.tabbar-operate{
-	position: fixed;
-	z-index: -20;
-	bottom: -200upx;
-	width: 100%;
-	left: 0;
-	padding: 0upx 30upx;
-	box-sizing: border-box;
-	text-align: center;
-	transition: 0.3s all;
-}
-.tabbar-operate.show{
-	bottom: 140upx;
-}
-.tabbar-operate-main{
-	width: 100%;
-	height: 200upx;
-	border-radius: 40upx;
-	padding-top: 18upx;
-	background: #fff;
-	box-shadow: 0px 0px 10upx rgba(0, 0, 0, 0.2);
-	overflow: hidden;
-}
-.tabbar-operate-main>view{
-	width: 25%;
-	float: left;
-}
-.tabbar-operate-main .index-sort-text{
-	font-size: 28upx;
-	font-weight: bold;
-}
-.tabbar-operate-bg{
-	position: fixed;
-	background-color: #000;
-	width: 100%;
-	height: calc(100vh - 100upx);
-	opacity: 0;
-	z-index: -30;
-	left: 0px;
-	top: 0px;
-	transition: 0.2s all;
-	visibility:hidden;
-}
-.tabbar-operate-bg.show{
-	opacity: 0.3;
-	visibility:visible;
-}
-.forum-operate{
-	position: fixed;
-	width: 200upx;
-	right: 30upx;
-	z-index: 20;
-	background: #fff;
-	color: #000;
-	overflow: hidden;
-	border-radius: 10upx;
-	font-size: 24upx;
-	padding: 10upx 0upx;
-	box-shadow: 0upx 0upx 4upx rgba(0, 0, 0, 0.3);
-}
-.forum-operate-box{
-	padding: 16upx 20upx;
-}
-.forum-operate-box text{
-	margin-right: 8upx;
-}
-.topList{
-	padding: 0upx 20upx 10upx 20upx;
-}
-.topList-box{
-	padding: 10upx;
-	text-align: center;
-}
-.topList-main{
-	padding: 30upx 15upx;
-	color: #0081ff;
-	border: none;
-	background-color: rgba(0, 129, 255, 0.15);
-	border-radius: 20upx;
-	font-size: 26upx;
-}
-.topList-main text{
-	display: block;
-	width: 100%;
-	font-size: 50upx;
-	margin-bottom: 10upx;
-}
-.topList .topList-box:nth-child(2) .topList-main{
-	color: #039a54;
-	background-color: rgba(3, 154, 84, 0.15);
-}
-.topList .topList-box:nth-child(3) .topList-main{
-	color: #f74c7c;
-	background-color:rgba(247,76,124, 0.15);
-}
-.invite{
-	padding:30upx;
-	text-align:center;
-}
-.invite-title{
-	font-size:32upx;
-	color: #000;
-	font-weight: bold;
-}
-.invite-pic{
-	padding: 20upx 0upx 0upx 0upx;
-}
-.invite-pic image{
-	width: 400upx;
-}
-.invite-text{
-	font-size: 50upx;
-	font-weight: bold;
-	margin-bottom: 30upx;
-}
-.home-section{
-	padding: 10upx 10upx 20upx 10upx;
-}
-.home-section-box{
-	padding: 10upx 10upx;
-	text-align: center;
-}
-.home-section-pic{
-	width: 190upx;
-	height: 190upx;
-	overflow: hidden;
-	margin: 0 auto;
-	border-radius: 10upx;
-}
-.home-section-pic image{
-	width: 100%;
-	background: #f3f3f3;
-	height: 100%;
-}
-.home-section-text{
-	margin-top: 10upx;
-}
-.home-section-title{
-	color: #000;
-	font-size: 30upx;
-	font-weight: bold;
-	text-overflow: -o-ellipsis-lastline;
-	overflow: hidden;
-	text-overflow: ellipsis;
-	display: -webkit-box;
-	-webkit-line-clamp: 1;
-	line-clamp: 1;
-	-webkit-box-orient: vertical;
-}
-.home-section-value{
-	font-size: 24upx;
-	color: #999;
-}
-.square-data-type{
-	text-align: right;
-	padding: 20upx 20upx 10upx 20upx;
-}
-.square-data-type text{
-	color: #999;
-	margin-left: 20upx;
-}
-.square-data-type text.cur{
-	color: #000;
-	font-weight: bold;
-}
-.shop-order-concent{
-	overflow: hidden;
-	padding: 20upx;
-	background: #fff;
-}
-.shop-order-concent .shop-order-img{
-	width: 140upx;
-	float: left;
-	height: 100upx;
-	overflow: hidden;
-	border-radius: 10upx;
-}
-.shop-order-concent .shop-order-title{
-	width: calc(100% - 200upx);
-	float: left;
-	padding-left: 20upx;
-	font-size: 34upx;
-	line-height: 48upx;
-	font-weight: bold;
-	text-overflow: -o-ellipsis-lastline;
-	overflow: hidden;
-	text-overflow: ellipsis;
-	display: -webkit-box;
-	-webkit-line-clamp:2;
-	line-clamp: 2;
-	-webkit-box-orient: vertical;
-}
-.user-title{
-	height: 70upx;
-	font-weight: bold;
-	color: #000;
-	line-height: 70upx;
-	padding: 0upx 30upx;
-}
-.identify-box{
-	background: #fff;
-	height:250upx;
-	margin-top: 10upx;
-}
-.identify-title{
-	line-height: 90upx;
-	height: 90upx;
-	padding: 0upx 30upx;
-	border-bottom: solid 1px #f6f6f6;
-}
-.identify-title-text{
-	color: #000;
-	font-size: 34upx;
-	font-weight: bold;
-}
-.identify-title .text-blue,.identify-title .text-orange,.identify-title .text-green{
-	float: right;
-}
-.identify-concent{
-	padding: 30upx;
-}
-.identify-tips{
-	padding: 30upx;
-	color: #666;
-}
-.identify-tips-title{
-	margin-bottom: 20upx;
-	color: #333;
-	font-size: 30upx;
-	font-weight: bold;
-}
-.identify-tips-p{
-	margin-bottom: 18upx;
-	line-height: 40upx;
-}
-.identify-item-box{
-	padding: 30upx;
-	border-bottom: solid 1px #f6f6f6;
-}
-.identify-box-btn{
-	float: right;
-}
-.identify-box-user{
-	margin-top: 18upx;
-}
-.identify-box-value{
-	color: #666;
-	line-height: 50upx;
-}
-.identify-box-value text{
-	font-weight: bold;
-	color: #333;
-	font-size: 36upx;
-}
-/**风格切换**/
-.full-blue .header .cu-bar.bg-white{
-	background-color: #0081ff;
-	color: #fff;
-}
-.full-pink .header .cu-bar.bg-white{
-	background-color: #fa7298;
-	color: #fff;
-}
-.full-orange .header .cu-bar.bg-white{
-	background-color: #f47c35;
-	color: #fff;
-}
-.full-green .header .cu-bar.bg-white{
-	background-color: #8ebe58;
-	color: #fff;
-}
-.userIndex.full-blue .header.goScroll{
-	background: #0081ff;
-}
-.userIndex.full-pink .header.goScroll{
-	background: #fa7298;
-}
-.userIndex.full-orange .header.goScroll{
-	background: #f47c35;
-}
-.userIndex.full-green .header.goScroll{
-	background: #8ebe58;
-}
-.upload-bg{
-	padding: 30upx;
-}
-.upload-bg-no{
-	background: #ddd;
-	width: 100%;
-	height: 380upx;
-	border-radius: 8upx;
-	text-align: center;
-	font-size: 36upx;
-	color: #666;
-	line-height: 360upx;
-}
-.upload-bg-box{
-	position: relative;
-	width: 100%;
-	height: 380upx;
-	border-radius: 8upx;
-	overflow: hidden;
-	text-align: center;
-}
-.upload-bg-box image{
-	width: 100%;
-}
-.reload-btn{
-	position: absolute;
-	top: 42%;
-	z-index: 5;
-	width: 100%;
-	color: #fff;
-	font-weight: bold;
-	font-size: 42upx;
-	text-shadow: 0px 0px 4upx #000;
-}
-

Разница между файлами не показана из-за своего большого размера
+ 0 - 36
chexnet-master-MP/style/icon.css


+ 0 - 3958
chexnet-master-MP/style/main.css

@@ -1,3958 +0,0 @@
-/* 
-body {
-	background-color: #f1f1f1;
-	font-size: 28upx;
-	color: #333333;
-	font-family: Helvetica Neue, Helvetica, sans-serif;
-} */
-
-view,
-scroll-view,
-swiper,
-button,
-input,
-textarea,
-label,
-navigator,
-image {
-	box-sizing: border-box;
-}
-
-.round {
-	border-radius: 5000upx;
-}
-
-.radius {
-	border-radius: 6upx;
-}
-
-/* ==================
-          图片
- ==================== */
-
-image {
-	max-width: 100%;
-	display: inline-block;
-	position: relative;
-	z-index: 0;
-}
-
-image.loading::before {
-	content: "";
-	background-color: #f5f5f5;
-	display: block;
-	position: absolute;
-	width: 100%;
-	height: 100%;
-	z-index: -2;
-}
-
-image.loading::after {
-	content: "\e7f1";
-	font-family: "cuIcon";
-	position: absolute;
-	top: 0;
-	left: 0;
-	width: 32upx;
-	height: 32upx;
-	line-height: 32upx;
-	right: 0;
-	bottom: 0;
-	z-index: -1;
-	font-size: 32upx;
-	margin: auto;
-	color: #ccc;
-	-webkit-animation: cuIcon-spin 2s infinite linear;
-	animation: cuIcon-spin 2s infinite linear;
-	display: block;
-}
-
-.response {
-	width: 100%;
-}
-
-/* ==================
-         开关
- ==================== */
-
-switch,
-checkbox,
-radio {
-	position: relative;
-}
-
-switch::after,
-switch::before {
-	font-family: "cuIcon";
-	content: "\e645";
-	position: absolute;
-	color: #ffffff !important;
-	top: 0%;
-	left: 0upx;
-	font-size: 26upx;
-	line-height: 26px;
-	width: 50%;
-	text-align: center;
-	pointer-events: none;
-	transform: scale(0, 0);
-	transition: all 0.3s ease-in-out 0s;
-	z-index: 9;
-	bottom: 0;
-	height: 26px;
-	margin: auto;
-}
-
-switch::before {
-	content: "\e646";
-	right: 0;
-	transform: scale(1, 1);
-	left: auto;
-}
-
-switch[checked]::after,
-switch.checked::after {
-	transform: scale(1, 1);
-}
-
-switch[checked]::before,
-switch.checked::before {
-	transform: scale(0, 0);
-}
-
-/* #ifndef MP-ALIPAY */
-radio::before,
-checkbox::before {
-	font-family: "cuIcon";
-	content: "\e645";
-	position: absolute;
-	color: #ffffff !important;
-	top: 50%;
-	margin-top: -8px;
-	right: 5px;
-	font-size: 32upx;
-	line-height: 16px;
-	pointer-events: none;
-	transform: scale(1, 1);
-	transition: all 0.3s ease-in-out 0s;
-	z-index: 9;
-}
-
-radio .wx-radio-input,
-checkbox .wx-checkbox-input,
-radio .uni-radio-input,
-checkbox .uni-checkbox-input {
-	margin: 0;
-	width: 24px;
-	height: 24px;
-}
-
-checkbox.round .wx-checkbox-input,
-checkbox.round .uni-checkbox-input {
-	border-radius: 100upx;
-}
-
-/* #endif */
-
-switch[checked]::before {
-	transform: scale(0, 0);
-}
-
-switch .wx-switch-input,
-switch .uni-switch-input {
-	border: none;
-	padding: 0 24px;
-	width: 48px;
-	height: 26px;
-	margin: 0;
-	border-radius: 100upx;
-}
-
-switch .wx-switch-input:not([class*="bg-"]),
-switch .uni-switch-input:not([class*="bg-"]) {
-	background: #8799a3 !important;
-}
-
-switch .wx-switch-input::after,
-switch .uni-switch-input::after {
-	margin: auto;
-	width: 26px;
-	height: 26px;
-	border-radius: 100upx;
-	left: 0upx;
-	top: 0upx;
-	bottom: 0upx;
-	position: absolute;
-	transform: scale(0.9, 0.9);
-	transition: all 0.1s ease-in-out 0s;
-}
-
-switch .wx-switch-input.wx-switch-input-checked::after,
-switch .uni-switch-input.uni-switch-input-checked::after {
-	margin: auto;
-	left: 22px;
-	box-shadow: none;
-	transform: scale(0.9, 0.9);
-}
-
-radio-group {
-	display: inline-block;
-}
-
-
-
-switch.radius .wx-switch-input::after,
-switch.radius .wx-switch-input,
-switch.radius .wx-switch-input::before,
-switch.radius .uni-switch-input::after,
-switch.radius .uni-switch-input,
-switch.radius .uni-switch-input::before {
-	border-radius: 10upx;
-}
-
-switch .wx-switch-input::before,
-radio.radio::before,
-checkbox .wx-checkbox-input::before,
-radio .wx-radio-input::before,
-switch .uni-switch-input::before,
-radio.radio::before,
-checkbox .uni-checkbox-input::before,
-radio .uni-radio-input::before {
-	display: none;
-}
-
-radio.radio[checked]::after,
-radio.radio .uni-radio-input-checked::after {
-	content: "";
-	background-color: transparent;
-	display: block;
-	position: absolute;
-	width: 8px;
-	height: 8px;
-	z-index: 999;
-	top: 0upx;
-	left: 0upx;
-	right: 0;
-	bottom: 0;
-	margin: auto;
-	border-radius: 200upx;
-	/* #ifndef MP */
-	border: 7px solid #ffffff !important;
-	/* #endif */
-
-	/* #ifdef MP */
-	border: 8px solid #ffffff !important;
-	/* #endif */
-}
-
-.switch-sex::after {
-	content: "\e71c";
-}
-
-.switch-sex::before {
-	content: "\e71a";
-}
-
-.switch-sex .wx-switch-input,
-.switch-sex .uni-switch-input {
-	background: #e54d42 !important;
-	border-color: #e54d42 !important;
-}
-
-.switch-sex[checked] .wx-switch-input,
-.switch-sex.checked .uni-switch-input {
-	background: #0081ff !important;
-	border-color: #0081ff !important;
-}
-
-switch.red[checked] .wx-switch-input.wx-switch-input-checked,
-checkbox.red[checked] .wx-checkbox-input,
-radio.red[checked] .wx-radio-input,
-switch.red.checked .uni-switch-input.uni-switch-input-checked,
-checkbox.red.checked .uni-checkbox-input,
-radio.red.checked .uni-radio-input {
-	background-color: #e54d42 !important;
-	border-color: #e54d42 !important;
-	color: #ffffff !important;
-}
-
-switch.orange[checked] .wx-switch-input,
-checkbox.orange[checked] .wx-checkbox-input,
-radio.orange[checked] .wx-radio-input,
-switch.orange.checked .uni-switch-input,
-checkbox.orange.checked .uni-checkbox-input,
-radio.orange.checked .uni-radio-input {
-	background-color: #f37b1d !important;
-	border-color: #f37b1d !important;
-	color: #ffffff !important;
-}
-
-switch.yellow[checked] .wx-switch-input,
-checkbox.yellow[checked] .wx-checkbox-input,
-radio.yellow[checked] .wx-radio-input,
-switch.yellow.checked .uni-switch-input,
-checkbox.yellow.checked .uni-checkbox-input,
-radio.yellow.checked .uni-radio-input {
-	background-color: #fbbd08 !important;
-	border-color: #fbbd08 !important;
-	color: #333333 !important;
-}
-
-switch.olive[checked] .wx-switch-input,
-checkbox.olive[checked] .wx-checkbox-input,
-radio.olive[checked] .wx-radio-input,
-switch.olive.checked .uni-switch-input,
-checkbox.olive.checked .uni-checkbox-input,
-radio.olive.checked .uni-radio-input {
-	background-color: #8dc63f !important;
-	border-color: #8dc63f !important;
-	color: #ffffff !important;
-}
-
-switch.green[checked] .wx-switch-input,
-switch[checked] .wx-switch-input,
-checkbox.green[checked] .wx-checkbox-input,
-checkbox[checked] .wx-checkbox-input,
-radio.green[checked] .wx-radio-input,
-radio[checked] .wx-radio-input,
-switch.green.checked .uni-switch-input,
-switch.checked .uni-switch-input,
-checkbox.green.checked .uni-checkbox-input,
-checkbox.checked .uni-checkbox-input,
-radio.green.checked .uni-radio-input,
-radio.checked .uni-radio-input {
-	background-color: #39b54a !important;
-	border-color: #39b54a !important;
-	color: #ffffff !important;
-	border-color: #39B54A !important;
-}
-
-switch.cyan[checked] .wx-switch-input,
-checkbox.cyan[checked] .wx-checkbox-input,
-radio.cyan[checked] .wx-radio-input,
-switch.cyan.checked .uni-switch-input,
-checkbox.cyan.checked .uni-checkbox-input,
-radio.cyan.checked .uni-radio-input {
-	background-color: #1cbbb4 !important;
-	border-color: #1cbbb4 !important;
-	color: #ffffff !important;
-}
-
-switch.blue[checked] .wx-switch-input,
-checkbox.blue[checked] .wx-checkbox-input,
-radio.blue[checked] .wx-radio-input,
-switch.blue.checked .uni-switch-input,
-checkbox.blue.checked .uni-checkbox-input,
-radio.blue.checked .uni-radio-input {
-	background-color: #0081ff !important;
-	border-color: #0081ff !important;
-	color: #ffffff !important;
-}
-
-switch.purple[checked] .wx-switch-input,
-checkbox.purple[checked] .wx-checkbox-input,
-radio.purple[checked] .wx-radio-input,
-switch.purple.checked .uni-switch-input,
-checkbox.purple.checked .uni-checkbox-input,
-radio.purple.checked .uni-radio-input {
-	background-color: #6739b6 !important;
-	border-color: #6739b6 !important;
-	color: #ffffff !important;
-}
-
-switch.mauve[checked] .wx-switch-input,
-checkbox.mauve[checked] .wx-checkbox-input,
-radio.mauve[checked] .wx-radio-input,
-switch.mauve.checked .uni-switch-input,
-checkbox.mauve.checked .uni-checkbox-input,
-radio.mauve.checked .uni-radio-input {
-	background-color: #9c26b0 !important;
-	border-color: #9c26b0 !important;
-	color: #ffffff !important;
-}
-
-switch.pink[checked] .wx-switch-input,
-checkbox.pink[checked] .wx-checkbox-input,
-radio.pink[checked] .wx-radio-input,
-switch.pink.checked .uni-switch-input,
-checkbox.pink.checked .uni-checkbox-input,
-radio.pink.checked .uni-radio-input {
-	background-color: #e03997 !important;
-	border-color: #e03997 !important;
-	color: #ffffff !important;
-}
-
-switch.brown[checked] .wx-switch-input,
-checkbox.brown[checked] .wx-checkbox-input,
-radio.brown[checked] .wx-radio-input,
-switch.brown.checked .uni-switch-input,
-checkbox.brown.checked .uni-checkbox-input,
-radio.brown.checked .uni-radio-input {
-	background-color: #a5673f !important;
-	border-color: #a5673f !important;
-	color: #ffffff !important;
-}
-
-switch.grey[checked] .wx-switch-input,
-checkbox.grey[checked] .wx-checkbox-input,
-radio.grey[checked] .wx-radio-input,
-switch.grey.checked .uni-switch-input,
-checkbox.grey.checked .uni-checkbox-input,
-radio.grey.checked .uni-radio-input {
-	background-color: #8799a3 !important;
-	border-color: #8799a3 !important;
-	color: #ffffff !important;
-}
-
-switch.gray[checked] .wx-switch-input,
-checkbox.gray[checked] .wx-checkbox-input,
-radio.gray[checked] .wx-radio-input,
-switch.gray.checked .uni-switch-input,
-checkbox.gray.checked .uni-checkbox-input,
-radio.gray.checked .uni-radio-input {
-	background-color: #f0f0f0 !important;
-	border-color: #f0f0f0 !important;
-	color: #333333 !important;
-}
-
-switch.black[checked] .wx-switch-input,
-checkbox.black[checked] .wx-checkbox-input,
-radio.black[checked] .wx-radio-input,
-switch.black.checked .uni-switch-input,
-checkbox.black.checked .uni-checkbox-input,
-radio.black.checked .uni-radio-input {
-	background-color: #333333 !important;
-	border-color: #333333 !important;
-	color: #ffffff !important;
-}
-
-switch.white[checked] .wx-switch-input,
-checkbox.white[checked] .wx-checkbox-input,
-radio.white[checked] .wx-radio-input,
-switch.white.checked .uni-switch-input,
-checkbox.white.checked .uni-checkbox-input,
-radio.white.checked .uni-radio-input {
-	background-color: #ffffff !important;
-	border-color: #ffffff !important;
-	color: #333333 !important;
-}
-
-/* ==================
-          边框
- ==================== */
-
-/* -- 实线 -- */
-
-.solid,
-.solid-top,
-.solid-right,
-.solid-bottom,
-.solid-left,
-.solids,
-.solids-top,
-.solids-right,
-.solids-bottom,
-.solids-left,
-.dashed,
-.dashed-top,
-.dashed-right,
-.dashed-bottom,
-.dashed-left {
-	position: relative;
-}
-
-.solid::after,
-.solid-top::after,
-.solid-right::after,
-.solid-bottom::after,
-.solid-left::after,
-.solids::after,
-.solids-top::after,
-.solids-right::after,
-.solids-bottom::after,
-.solids-left::after,
-.dashed::after,
-.dashed-top::after,
-.dashed-right::after,
-.dashed-bottom::after,
-.dashed-left::after {
-	content: " ";
-	width: 200%;
-	height: 200%;
-	position: absolute;
-	top: 0;
-	left: 0;
-	border-radius: inherit;
-	transform: scale(0.5);
-	transform-origin: 0 0;
-	pointer-events: none;
-	box-sizing: border-box;
-}
-
-.solid::after {
-	border: 1upx solid rgba(0, 0, 0, 0.1);
-}
-
-.solid-top::after {
-	border-top: 1upx solid rgba(0, 0, 0, 0.1);
-}
-
-.solid-right::after {
-	border-right: 1upx solid rgba(0, 0, 0, 0.1);
-}
-
-.solid-bottom::after {
-	border-bottom: 1upx solid rgba(0, 0, 0, 0.1);
-}
-
-.solid-left::after {
-	border-left: 1upx solid rgba(0, 0, 0, 0.1);
-}
-
-.solids::after {
-	border: 8upx solid #eee;
-}
-
-.solids-top::after {
-	border-top: 8upx solid #eee;
-}
-
-.solids-right::after {
-	border-right: 8upx solid #eee;
-}
-
-.solids-bottom::after {
-	border-bottom: 8upx solid #eee;
-}
-
-.solids-left::after {
-	border-left: 8upx solid #eee;
-}
-
-/* -- 虚线 -- */
-
-.dashed::after {
-	border: 1upx dashed #ddd;
-}
-
-.dashed-top::after {
-	border-top: 1upx dashed #ddd;
-}
-
-.dashed-right::after {
-	border-right: 1upx dashed #ddd;
-}
-
-.dashed-bottom::after {
-	border-bottom: 1upx dashed #ddd;
-}
-
-.dashed-left::after {
-	border-left: 1upx dashed #ddd;
-}
-
-/* -- 阴影 -- */
-
-.shadow[class*='white'] {
-	--ShadowSize: 0 1upx 6upx;
-}
-
-.shadow-lg {
-	--ShadowSize: 0upx 40upx 100upx 0upx;
-}
-
-.shadow-warp {
-	position: relative;
-	box-shadow: 0 0 10upx rgba(0, 0, 0, 0.1);
-}
-
-.shadow-warp:before,
-.shadow-warp:after {
-	position: absolute;
-	content: "";
-	top: 20upx;
-	bottom: 30upx;
-	left: 20upx;
-	width: 50%;
-	box-shadow: 0 30upx 20upx rgba(0, 0, 0, 0.2);
-	transform: rotate(-3deg);
-	z-index: -1;
-}
-
-.shadow-warp:after {
-	right: 20upx;
-	left: auto;
-	transform: rotate(3deg);
-}
-
-.shadow-blur {
-	position: relative;
-}
-
-.shadow-blur::before {
-	content: "";
-	display: block;
-	background: inherit;
-	filter: blur(10upx);
-	position: absolute;
-	width: 100%;
-	height: 100%;
-	top: 10upx;
-	left: 10upx;
-	z-index: -1;
-	opacity: 0.4;
-	transform-origin: 0 0;
-	border-radius: inherit;
-	transform: scale(1, 1);
-}
-
-/* ==================
-          按钮
- ==================== */
-
-.cu-btn {
-	position: relative;
-	border: 0upx;
-	display: inline-flex;
-	align-items: center;
-	justify-content: center;
-	box-sizing: border-box;
-	padding: 0 30upx;
-	font-size: 28upx;
-	height: 64upx;
-	line-height: 1;
-	text-align: center;
-	text-decoration: none;
-	overflow: visible;
-	margin-left: initial;
-	transform: translate(0upx, 0upx);
-	margin-right: initial;
-}
-
-.cu-btn::after {
-	display: none;
-}
-
-.cu-btn:not([class*="bg-"]) {
-	background-color: #f0f0f0;
-}
-
-.cu-btn[class*="line"] {
-	background-color: transparent;
-}
-
-.cu-btn[class*="line"]::after {
-	content: " ";
-	display: block;
-	width: 200%;
-	height: 200%;
-	position: absolute;
-	top: 0;
-	left: 0;
-	border: 1upx solid currentColor;
-	transform: scale(0.5);
-	transform-origin: 0 0;
-	box-sizing: border-box;
-	border-radius: 12upx;
-	z-index: 1;
-	pointer-events: none;
-}
-
-.cu-btn.round[class*="line"]::after {
-	border-radius: 1000upx;
-}
-
-.cu-btn[class*="lines"]::after {
-	border: 6upx solid currentColor;
-}
-
-.cu-btn[class*="bg-"]::after {
-	display: none;
-}
-
-.cu-btn.sm {
-	padding: 0 20upx;
-	font-size: 20upx;
-	height: 48upx;
-}
-
-.cu-btn.lg {
-	padding: 0 40upx;
-	font-size: 32upx;
-	height: 80upx;
-}
-
-.cu-btn.cuIcon.sm {
-	width: 48upx;
-	height: 48upx;
-}
-
-.cu-btn.cuIcon {
-	width: 64upx;
-	height: 64upx;
-	border-radius: 500upx;
-	padding: 0;
-}
-
-button.cuIcon.lg {
-	width: 80upx;
-	height: 80upx;
-}
-
-.cu-btn.shadow-blur::before {
-	top: 4upx;
-	left: 4upx;
-	filter: blur(6upx);
-	opacity: 0.6;
-}
-
-.cu-btn.button-hover {
-	transform: translate(1upx, 1upx);
-}
-
-.block {
-	display: block;
-}
-
-.cu-btn.block {
-	display: flex;
-}
-
-.cu-btn[disabled] {
-	opacity: 0.6;
-	color: #ffffff;
-}
-
-/* ==================
-          徽章
- ==================== */
-
-.cu-tag {
-	font-size: 24upx;
-	vertical-align: middle;
-	position: relative;
-	display: inline-flex;
-	align-items: center;
-	justify-content: center;
-	box-sizing: border-box;
-	padding: 0upx 16upx;
-	height: 48upx;
-	font-family: Helvetica Neue, Helvetica, sans-serif;
-	white-space: nowrap;
-}
-
-.cu-tag:not([class*="bg"]):not([class*="line"]) {
-	background-color: #f1f1f1;
-}
-
-.cu-tag[class*="line-"]::after {
-	content: " ";
-	width: 200%;
-	height: 200%;
-	position: absolute;
-	top: 0;
-	left: 0;
-	border: 1upx solid currentColor;
-	transform: scale(0.5);
-	transform-origin: 0 0;
-	box-sizing: border-box;
-	border-radius: inherit;
-	z-index: 1;
-	pointer-events: none;
-}
-
-.cu-tag.radius[class*="line"]::after {
-	border-radius: 12upx;
-}
-
-.cu-tag.round[class*="line"]::after {
-	border-radius: 1000upx;
-}
-
-.cu-tag[class*="line-"]::after {
-	border-radius: 0;
-}
-
-.cu-tag+.cu-tag {
-	margin-left: 10upx;
-}
-
-.cu-tag.sm {
-	font-size: 20upx;
-	padding: 0upx 12upx;
-	height: 32upx;
-}
-
-.cu-capsule {
-	display: inline-flex;
-	vertical-align: middle;
-}
-
-.cu-capsule+.cu-capsule {
-	margin-left: 10upx;
-}
-
-.cu-capsule .cu-tag {
-	margin: 0;
-}
-
-.cu-capsule .cu-tag[class*="line-"]:last-child::after {
-	border-left: 0upx solid transparent;
-}
-
-.cu-capsule .cu-tag[class*="line-"]:first-child::after {
-	border-right: 0upx solid transparent;
-}
-
-.cu-capsule.radius .cu-tag:first-child {
-	border-top-left-radius: 6upx;
-	border-bottom-left-radius: 6upx;
-}
-
-.cu-capsule.radius .cu-tag:last-child::after,
-.cu-capsule.radius .cu-tag[class*="line-"] {
-	border-top-right-radius: 12upx;
-	border-bottom-right-radius: 12upx;
-}
-
-.cu-capsule.round .cu-tag:first-child {
-	border-top-left-radius: 200upx;
-	border-bottom-left-radius: 200upx;
-	text-indent: 4upx;
-}
-
-.cu-capsule.round .cu-tag:last-child::after,
-.cu-capsule.round .cu-tag:last-child {
-	border-top-right-radius: 200upx;
-	border-bottom-right-radius: 200upx;
-	text-indent: -4upx;
-}
-
-.cu-tag.badge {
-	border-radius: 200upx;
-	position: absolute;
-	top: -10upx;
-	right: -10upx;
-	font-size: 20upx;
-	padding: 0upx 10upx;
-	height: 28upx;
-	color: #ffffff;
-}
-
-.cu-tag.badge:not([class*="bg-"]) {
-	background-color: #dd514c;
-}
-
-.cu-tag:empty:not([class*="cuIcon-"]) {
-	padding: 0upx;
-	width: 16upx;
-	height: 16upx;
-	top: -4upx;
-	right: -4upx;
-}
-
-.cu-tag[class*="cuIcon-"] {
-	width: 32upx;
-	height: 32upx;
-	top: -4upx;
-	right: -4upx;
-}
-
-/* ==================
-          头像
- ==================== */
-
-.cu-avatar {
-	font-variant: small-caps;
-	margin: 0;
-	padding: 0;
-	display: inline-flex;
-	text-align: center;
-	justify-content: center;
-	align-items: center;
-	background-color: #ccc;
-	color: #ffffff;
-	white-space: nowrap;
-	position: relative;
-	width: 64upx;
-	height: 64upx;
-	background-size: cover;
-	background-position: center;
-	vertical-align: middle;
-	font-size: 1.5em;
-}
-
-.cu-avatar.sm {
-	width: 48upx;
-	height: 48upx;
-	font-size: 1em;
-}
-
-.cu-avatar.lg {
-	width: 96upx;
-	height: 96upx;
-	font-size: 2em;
-}
-
-.cu-avatar.xl {
-	width: 128upx;
-	height: 128upx;
-	font-size: 2.5em;
-}
-
-.cu-avatar .avatar-text {
-	font-size: 0.4em;
-}
-
-.cu-avatar-group {
-	direction: rtl;
-	unicode-bidi: bidi-override;
-	padding: 0 10upx 0 40upx;
-	display: inline-block;
-}
-
-.cu-avatar-group .cu-avatar {
-	margin-left: -30upx;
-	border: 4upx solid #f1f1f1;
-	vertical-align: middle;
-}
-
-.cu-avatar-group .cu-avatar.sm {
-	margin-left: -20upx;
-	border: 1upx solid #f1f1f1;
-}
-
-/* ==================
-         进度条
- ==================== */
-
-.cu-progress {
-	overflow: hidden;
-	height: 28upx;
-	background-color: #ebeef5;
-	display: inline-flex;
-	align-items: center;
-	width: 100%;
-}
-
-.cu-progress+view,
-.cu-progress+text {
-	line-height: 1;
-}
-
-.cu-progress.xs {
-	height: 10upx;
-}
-
-.cu-progress.sm {
-	height: 20upx;
-}
-
-.cu-progress view {
-	width: 0;
-	height: 100%;
-	align-items: center;
-	display: flex;
-	justify-items: flex-end;
-	justify-content: space-around;
-	font-size: 20upx;
-	color: #ffffff;
-	transition: width 0.6s ease;
-}
-
-.cu-progress text {
-	align-items: center;
-	display: flex;
-	font-size: 20upx;
-	color: #333333;
-	text-indent: 10upx;
-}
-
-.cu-progress.text-progress {
-	padding-right: 60upx;
-}
-
-.cu-progress.striped view {
-	background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-	background-size: 72upx 72upx;
-}
-
-.cu-progress.active view {
-	animation: progress-stripes 2s linear infinite;
-}
-
-@keyframes progress-stripes {
-	from {
-		background-position: 72upx 0;
-	}
-
-	to {
-		background-position: 0 0;
-	}
-}
-
-/* ==================
-          加载
- ==================== */
-
-.cu-load {
-	display: block;
-	line-height: 3em;
-	text-align: center;
-}
-
-.cu-load::before {
-	font-family: "cuIcon";
-	display: inline-block;
-	margin-right: 6upx;
-}
-
-.cu-load.loading::before {
-	content: "\e67a";
-	animation: cuIcon-spin 2s infinite linear;
-}
-
-.cu-load.loading::after {
-	content: "加载中...";
-}
-
-.cu-load.over::before {
-	content: "\e64a";
-}
-
-.cu-load.over::after {
-	content: "没有更多了";
-}
-
-.cu-load.erro::before {
-	content: "\e658";
-}
-
-.cu-load.erro::after {
-	content: "加载失败";
-}
-
-.cu-load.load-cuIcon::before {
-	font-size: 32upx;
-}
-
-.cu-load.load-cuIcon::after {
-	display: none;
-}
-
-.cu-load.load-cuIcon.over {
-	display: none;
-}
-
-.cu-load.load-modal {
-	position: fixed;
-	top: 0;
-	right: 0;
-	bottom: 140upx;
-	left: 0;
-	margin: auto;
-	width: 260upx;
-	height: 260upx;
-	background-color: #ffffff;
-	border-radius: 10upx;
-	box-shadow: 0 0 0upx 2000upx rgba(0, 0, 0, 0.5);
-	display: flex;
-	align-items: center;
-	flex-direction: column;
-	justify-content: center;
-	font-size: 28upx;
-	z-index: 9999;
-	line-height: 2.4em;
-}
-
-.cu-load.load-modal [class*="cuIcon-"] {
-	font-size: 60upx;
-}
-
-.cu-load.load-modal image {
-	width: 70upx;
-	height: 70upx;
-}
-
-.cu-load.load-modal::after {
-	content: "";
-	position: absolute;
-	background-color: #ffffff;
-	border-radius: 50%;
-	width: 200upx;
-	height: 200upx;
-	font-size: 10px;
-	border-top: 6upx solid rgba(0, 0, 0, 0.05);
-	border-right: 6upx solid rgba(0, 0, 0, 0.05);
-	border-bottom: 6upx solid rgba(0, 0, 0, 0.05);
-	border-left: 6upx solid #f37b1d;
-	animation: cuIcon-spin 1s infinite linear;
-	z-index: -1;
-}
-
-.load-progress {
-	pointer-events: none;
-	top: 0;
-	position: fixed;
-	width: 100%;
-	left: 0;
-	z-index: 2000;
-}
-
-.load-progress.hide {
-	display: none;
-}
-
-.load-progress .load-progress-bar {
-	position: relative;
-	width: 100%;
-	height: 4upx;
-	overflow: hidden;
-	transition: all 200ms ease 0s;
-}
-
-.load-progress .load-progress-spinner {
-	position: absolute;
-	top: 10upx;
-	right: 10upx;
-	z-index: 2000;
-	display: block;
-}
-
-.load-progress .load-progress-spinner::after {
-	content: "";
-	display: block;
-	width: 24upx;
-	height: 24upx;
-	-webkit-box-sizing: border-box;
-	box-sizing: border-box;
-	border: solid 4upx transparent;
-	border-top-color: inherit;
-	border-left-color: inherit;
-	border-radius: 50%;
-	-webkit-animation: load-progress-spinner 0.4s linear infinite;
-	animation: load-progress-spinner 0.4s linear infinite;
-}
-
-@-webkit-keyframes load-progress-spinner {
-	0% {
-		-webkit-transform: rotate(0);
-		transform: rotate(0);
-	}
-
-	100% {
-		-webkit-transform: rotate(360deg);
-		transform: rotate(360deg);
-	}
-}
-
-@keyframes load-progress-spinner {
-	0% {
-		-webkit-transform: rotate(0);
-		transform: rotate(0);
-	}
-
-	100% {
-		-webkit-transform: rotate(360deg);
-		transform: rotate(360deg);
-	}
-}
-
-/* ==================
-          列表
- ==================== */
-.grayscale {
-	filter: grayscale(1);
-}
-
-.cu-list+.cu-list {
-	margin-top: 30upx
-}
-
-.cu-list>.cu-item {
-	transition: all .6s ease-in-out 0s;
-	transform: translateX(0upx)
-}
-
-.cu-list>.cu-item.move-cur {
-	transform: translateX(-260upx)
-}
-
-.cu-list>.cu-item .move {
-	position: absolute;
-	right: 0;
-	display: flex;
-	width: 260upx;
-	height: 100%;
-	transform: translateX(100%)
-}
-
-.cu-list>.cu-item .move view {
-	display: flex;
-	flex: 1;
-	justify-content: center;
-	align-items: center
-}
-
-.cu-list.menu-avatar {
-	overflow: hidden;
-}
-
-.cu-list.menu-avatar>.cu-item {
-	position: relative;
-	display: flex;
-	padding-right: 10upx;
-	height: 140upx;
-	background-color: #ffffff;
-	justify-content: flex-end;
-	align-items: center
-}
-
-.cu-list.menu-avatar>.cu-item>.cu-avatar {
-	position: absolute;
-	left: 30upx
-}
-
-.cu-list.menu-avatar>.cu-item .flex .text-cut {
-	max-width: 510upx
-}
-
-.cu-list.menu-avatar>.cu-item .content {
-	position: absolute;
-	left: 146upx;
-	width: calc(100% - 96upx - 60upx - 120upx - 20upx);
-	line-height: 1.6em;
-}
-
-.cu-list.menu-avatar>.cu-item .content.flex-sub {
-	width: calc(100% - 96upx - 60upx - 20upx);
-}
-
-.cu-list.menu-avatar>.cu-item .content>view:first-child {
-	font-size: 30upx;
-	display: flex;
-	align-items: center
-}
-
-.cu-list.menu-avatar>.cu-item .content .cu-tag.sm {
-	display: inline-block;
-	margin-left: 10upx;
-	height: 28upx;
-	font-size: 16upx;
-	line-height: 32upx
-}
-
-.cu-list.menu-avatar>.cu-item .action {
-	width: 100upx;
-	text-align: center
-}
-
-.cu-list.menu-avatar>.cu-item .action view+view {
-	margin-top: 10upx
-}
-
-.cu-list.menu-avatar.comment>.cu-item .content {
-	position: relative;
-	left: 0;
-	width: auto;
-	flex: 1;
-}
-
-.cu-list.menu-avatar.comment>.cu-item {
-	padding: 30upx 30upx 30upx 120upx;
-	height: auto
-}
-
-.cu-list.menu-avatar.comment .cu-avatar {
-	align-self: flex-start
-}
-
-.cu-list.menu>.cu-item {
-	position: relative;
-	display: flex;
-	padding: 0 30upx;
-	min-height: 100upx;
-	background-color: #ffffff;
-	justify-content: space-between;
-	align-items: center
-}
-
-.cu-list.menu>.cu-item:last-child:after {
-	border: none
-}
-
-.cu-list.menu-avatar>.cu-item:after,
-.cu-list.menu>.cu-item:after {
-	position: absolute;
-	top: 0;
-	left: 0;
-	box-sizing: border-box;
-	width: 200%;
-	height: 200%;
-	border-bottom: 1upx solid #ddd;
-	border-radius: inherit;
-	content: " ";
-	transform: scale(.5);
-	transform-origin: 0 0;
-	pointer-events: none
-}
-
-.cu-list.menu>.cu-item.grayscale {
-	background-color: #f5f5f5
-}
-
-.cu-list.menu>.cu-item.cur {
-	background-color: #fcf7e9
-}
-
-.cu-list.menu>.cu-item.arrow {
-	padding-right: 90upx
-}
-
-.cu-list.menu>.cu-item.arrow:before {
-	position: absolute;
-	top: 0;
-	right: 30upx;
-	bottom: 0;
-	display: block;
-	margin: auto;
-	width: 30upx;
-	height: 30upx;
-	color: #8799a3;
-	content: "\e6a3";
-	text-align: center;
-	font-size: 34upx;
-	font-family: cuIcon;
-	line-height: 30upx
-}
-
-.cu-list.menu>.cu-item button.content {
-	padding: 0;
-	background-color: transparent;
-	justify-content: flex-start
-}
-
-.cu-list.menu>.cu-item button.content:after {
-	display: none
-}
-
-.cu-list.menu>.cu-item .cu-avatar-group .cu-avatar {
-	border-color: #ffffff
-}
-
-.cu-list.menu>.cu-item .content>view:first-child {
-	display: flex;
-	align-items: center
-}
-
-.cu-list.menu>.cu-item .content>text[class*=cuIcon] {
-	display: inline-block;
-	margin-right: 10upx;
-	width: 1.6em;
-	text-align: center
-}
-
-.cu-list.menu>.cu-item .content>image {
-	display: inline-block;
-	margin-right: 10upx;
-	width: 1.6em;
-	height: 1.6em;
-	vertical-align: middle
-}
-
-.cu-list.menu>.cu-item .content {
-	font-size: 30upx;
-	line-height: 1.6em;
-	flex: 1
-}
-
-.cu-list.menu>.cu-item .content .cu-tag.sm {
-	display: inline-block;
-	margin-left: 10upx;
-	height: 28upx;
-	font-size: 16upx;
-	line-height: 32upx
-}
-
-.cu-list.menu>.cu-item .action .cu-tag:empty {
-	right: 10upx
-}
-
-.cu-list.menu {
-	display: block;
-	overflow: hidden
-}
-
-.cu-list.menu.sm-border>.cu-item:after {
-	left: 30upx;
-	width: calc(200% - 120upx)
-}
-
-.cu-list.grid>.cu-item {
-	position: relative;
-	display: flex;
-	padding: 20upx 0 30upx;
-	transition-duration: 0s;
-	flex-direction: column
-}
-
-.cu-list.grid>.cu-item:after {
-	position: absolute;
-	top: 0;
-	left: 0;
-	box-sizing: border-box;
-	width: 200%;
-	height: 200%;
-	border-right: 1px solid rgba(0, 0, 0, .1);
-	border-bottom: 1px solid rgba(0, 0, 0, .1);
-	border-radius: inherit;
-	content: " ";
-	transform: scale(.5);
-	transform-origin: 0 0;
-	pointer-events: none
-}
-
-.cu-list.grid>.cu-item text {
-	display: block;
-	margin-top: 10upx;
-	color: #888;
-	font-size: 26upx;
-	line-height: 40upx
-}
-
-.cu-list.grid>.cu-item [class*=cuIcon] {
-	position: relative;
-	display: block;
-	margin-top: 20upx;
-	width: 100%;
-	font-size: 48upx
-}
-
-.cu-list.grid>.cu-item .cu-tag {
-	right: auto;
-	left: 50%;
-	margin-left: 20upx
-}
-
-.cu-list.grid {
-	background-color: #ffffff;
-	text-align: center
-}
-
-.cu-list.grid.no-border>.cu-item {
-	padding-top: 10upx;
-	padding-bottom: 20upx
-}
-
-.cu-list.grid.no-border>.cu-item:after {
-	border: none
-}
-
-.cu-list.grid.no-border {
-	padding: 20upx 10upx
-}
-
-.cu-list.grid.col-3>.cu-item:nth-child(3n):after,
-.cu-list.grid.col-4>.cu-item:nth-child(4n):after,
-.cu-list.grid.col-5>.cu-item:nth-child(5n):after {
-	border-right-width: 0
-}
-
-.cu-list.card-menu {
-	overflow: hidden;
-	margin-right: 30upx;
-	margin-left: 30upx;
-	border-radius: 20upx
-}
-
-
-/* ==================
-          操作条
- ==================== */
-
-.cu-bar {
-	display: flex;
-	position: relative;
-	align-items: center;
-	min-height: 100upx;
-	justify-content: space-between;
-}
-
-.cu-bar .action {
-	display: flex;
-	align-items: center;
-	height: 100%;
-	justify-content: center;
-	max-width: 100%;
-}
-
-.cu-bar .action.border-title {
-	position: relative;
-	top: -10upx;
-}
-
-.cu-bar .action.border-title text[class*="bg-"]:last-child {
-	position: absolute;
-	bottom: -0.5rem;
-	min-width: 2rem;
-	height: 6upx;
-	left: 0;
-}
-
-.cu-bar .action.sub-title {
-	position: relative;
-	top: -0.2rem;
-}
-
-.cu-bar .action.sub-title text {
-	position: relative;
-	z-index: 1;
-}
-
-.cu-bar .action.sub-title text[class*="bg-"]:last-child {
-	position: absolute;
-	display: inline-block;
-	bottom: -0.2rem;
-	border-radius: 6upx;
-	width: 100%;
-	height: 0.6rem;
-	left: 0.6rem;
-	opacity: 0.3;
-	z-index: 0;
-}
-
-.cu-bar .action.sub-title text[class*="text-"]:last-child {
-	position: absolute;
-	display: inline-block;
-	bottom: -0.7rem;
-	left: 0.5rem;
-	opacity: 0.2;
-	z-index: 0;
-	text-align: right;
-	font-weight: 900;
-	font-size: 36upx;
-}
-
-.cu-bar.justify-center .action.border-title text:last-child,
-.cu-bar.justify-center .action.sub-title text:last-child {
-	left: 0;
-	right: 0;
-	margin: auto;
-	text-align: center;
-}
-
-.cu-bar .action:first-child {
-	margin-left: 30upx;
-	font-size: 30upx;
-}
-
-.cu-bar .action text.text-cut {
-	text-align: left;
-	width: 100%;
-}
-
-.cu-bar .cu-avatar:first-child {
-	margin-left: 20upx;
-}
-
-.cu-bar .action:first-child>text[class*="cuIcon-"] {
-	margin-left: -0.3em;
-	margin-right: 0.3em;
-}
-
-.cu-bar .action:last-child {
-	margin-right: 30upx;
-}
-
-.cu-bar .action>text[class*="cuIcon-"],
-.cu-bar .action>view[class*="cuIcon-"] {
-	font-size: 36upx;
-}
-
-.cu-bar .action>text[class*="cuIcon-"]+text[class*="cuIcon-"] {
-	margin-left: 0.5em;
-}
-
-.cu-bar .content {
-	position: absolute;
-	text-align: center;
-	width: calc(100% - 340upx);
-	left: 0;
-	right: 0;
-	bottom: 0;
-	top: 0;
-	margin: auto;
-	height: 60upx;
-	font-size: 32upx;
-	line-height: 60upx;
-	cursor: none;
-	pointer-events: none;
-	text-overflow: ellipsis;
-	white-space: nowrap;
-	overflow: hidden;
-}
-
-.cu-bar.ios .content {
-	bottom: 7px;
-	height: 30px;
-	font-size: 32upx;
-	line-height: 30px;
-}
-
-.cu-bar.btn-group {
-	justify-content: space-around;
-}
-
-.cu-bar.btn-group button {
-	padding: 20upx 32upx;
-}
-
-.cu-bar.btn-group button {
-	flex: 1;
-	margin: 0 20upx;
-	max-width: 50%;
-}
-
-.cu-bar .search-form {
-	background-color: #f5f5f5;
-	line-height: 64upx;
-	height: 64upx;
-	font-size: 24upx;
-	color: #333333;
-	flex: 1;
-	display: flex;
-	align-items: center;
-	margin: 0 30upx;
-}
-
-.cu-bar .search-form+.action {
-	margin-right: 30upx;
-}
-
-.cu-bar .search-form input {
-	flex: 1;
-	padding-right: 30upx;
-	height: 64upx;
-	line-height: 64upx;
-	font-size: 26upx;
-	background-color: transparent;
-}
-
-.cu-bar .search-form [class*="cuIcon-"] {
-	margin: 0 0.5em 0 0.8em;
-}
-
-.cu-bar .search-form [class*="cuIcon-"]::before {
-	top: 0upx;
-}
-
-.cu-bar.fixed,
-.nav.fixed {
-	position: fixed;
-	width: 100%;
-	top: 0;
-	z-index: 1024;
-	box-shadow: 0 1upx 6upx rgba(0, 0, 0, 0.1);
-}
-
-.cu-bar.foot {
-	position: fixed;
-	width: 100%;
-	bottom: 0;
-	z-index: 1024;
-	box-shadow: 0 -1upx 6upx rgba(0, 0, 0, 0.1);
-}
-
-.cu-bar.tabbar {
-	padding: 0;
-	height: calc(100upx + env(safe-area-inset-bottom) / 2);
-	padding-bottom: calc(env(safe-area-inset-bottom) / 2);
-}
-
-.cu-tabbar-height {
-	min-height: 100upx;
-	height: calc(100upx + env(safe-area-inset-bottom) / 2);
-}
-
-.cu-bar.tabbar.shadow {
-	box-shadow: 0 -1upx 6upx rgba(0, 0, 0, 0.1);
-}
-
-.cu-bar.tabbar .action {
-	font-size: 22upx;
-	position: relative;
-	flex: 1;
-	text-align: center;
-	padding: 0;
-	display: block;
-	height: auto;
-	line-height: 1;
-	margin: 0;
-	background-color: inherit;
-	overflow: initial;
-}
-
-.cu-bar.tabbar.shop .action {
-	width: 140upx;
-	flex: initial;
-}
-
-.cu-bar.tabbar .action.add-action {
-	position: relative;
-	z-index: 2;
-	padding-top: 50upx;
-}
-
-.cu-bar.tabbar .action.add-action [class*="cuIcon-"] {
-	position: absolute;
-	width: 70upx;
-	z-index: 2;
-	height: 70upx;
-	border-radius: 50%;
-	line-height: 70upx;
-	font-size: 50upx;
-	top: -35upx;
-	left: 0;
-	right: 0;
-	margin: auto;
-	padding: 0;
-}
-
-.cu-bar.tabbar .action.add-action::after {
-	content: "";
-	position: absolute;
-	width: 100upx;
-	height: 100upx;
-	top: -50upx;
-	left: 0;
-	right: 0;
-	margin: auto;
-	box-shadow: 0 -3upx 8upx rgba(0, 0, 0, 0.08);
-	border-radius: 50upx;
-	background-color: inherit;
-	z-index: 0;
-}
-
-.cu-bar.tabbar .action.add-action::before {
-	content: "";
-	position: absolute;
-	width: 100upx;
-	height: 30upx;
-	bottom: 30upx;
-	left: 0;
-	right: 0;
-	margin: auto;
-	background-color: inherit;
-	z-index: 1;
-}
-
-.cu-bar.tabbar .btn-group {
-	flex: 1;
-	display: flex;
-	justify-content: space-around;
-	align-items: center;
-	padding: 0 10upx;
-}
-
-.cu-bar.tabbar button.action::after {
-	border: 0;
-}
-
-.cu-bar.tabbar .action [class*="cuIcon-"] {
-	width: 100upx;
-	position: relative;
-	display: block;
-	height: auto;
-	margin: 0 auto 10upx;
-	text-align: center;
-	font-size: 40upx;
-}
-
-.cu-bar.tabbar .action .cuIcon-cu-image {
-	margin: 0 auto;
-}
-
-.cu-bar.tabbar .action .cuIcon-cu-image image {
-	width: 50upx;
-	height: 50upx;
-	display: inline-block;
-}
-
-.cu-bar.tabbar .submit {
-	align-items: center;
-	display: flex;
-	justify-content: center;
-	text-align: center;
-	position: relative;
-	flex: 2;
-	align-self: stretch;
-}
-
-.cu-bar.tabbar .submit:last-child {
-	flex: 2.6;
-}
-
-.cu-bar.tabbar .submit+.submit {
-	flex: 2;
-}
-
-.cu-bar.tabbar.border .action::before {
-	content: " ";
-	width: 200%;
-	height: 200%;
-	position: absolute;
-	top: 0;
-	left: 0;
-	transform: scale(0.5);
-	transform-origin: 0 0;
-	border-right: 1upx solid rgba(0, 0, 0, 0.1);
-	z-index: 3;
-}
-
-.cu-bar.tabbar.border .action:last-child:before {
-	display: none;
-}
-
-.cu-bar.input {
-	padding-right: 20upx;
-	background-color: #ffffff;
-}
-
-.cu-bar.input input {
-	overflow: initial;
-	line-height: 64upx;
-	height: 64upx;
-	min-height: 64upx;
-	flex: 1;
-	font-size: 30upx;
-	margin: 0 20upx;
-}
-
-.cu-bar.input .action {
-	margin-left: 20upx;
-}
-
-.cu-bar.input .action [class*="cuIcon-"] {
-	font-size: 48upx;
-}
-
-.cu-bar.input input+.action {
-	margin-right: 20upx;
-	margin-left: 0upx;
-}
-
-.cu-bar.input .action:first-child [class*="cuIcon-"] {
-	margin-left: 0upx;
-}
-
-.cu-custom {
-	display: block;
-	position: relative;
-}
-
-.cu-custom .cu-bar .content {
-	width: calc(100% - 440upx);
-}
-
-/* #ifdef MP-ALIPAY */
-.cu-custom .cu-bar .action .cuIcon-back {
-	opacity: 0;
-}
-
-/* #endif */
-
-.cu-custom .cu-bar .content image {
-	height: 60upx;
-	width: 240upx;
-}
-
-.cu-custom .cu-bar {
-	min-height: 0px;
-	/* #ifdef MP-WEIXIN */
-	padding-right: 220upx;
-	/* #endif */
-	/* #ifdef MP-ALIPAY */
-	padding-right: 150upx;
-	/* #endif */
-	box-shadow: 0upx 0upx 0upx;
-	z-index: 9999;
-}
-
-.cu-custom .cu-bar .border-custom {
-	position: relative;
-	background: rgba(0, 0, 0, 0.15);
-	border-radius: 1000upx;
-	height: 30px;
-}
-
-.cu-custom .cu-bar .border-custom::after {
-	content: " ";
-	width: 200%;
-	height: 200%;
-	position: absolute;
-	top: 0;
-	left: 0;
-	border-radius: inherit;
-	transform: scale(0.5);
-	transform-origin: 0 0;
-	pointer-events: none;
-	box-sizing: border-box;
-	border: 1upx solid #ffffff;
-	opacity: 0.5;
-}
-
-.cu-custom .cu-bar .border-custom::before {
-	content: " ";
-	width: 1upx;
-	height: 110%;
-	position: absolute;
-	top: 22.5%;
-	left: 0;
-	right: 0;
-	margin: auto;
-	transform: scale(0.5);
-	transform-origin: 0 0;
-	pointer-events: none;
-	box-sizing: border-box;
-	opacity: 0.6;
-	background-color: #ffffff;
-}
-
-.cu-custom .cu-bar .border-custom text {
-	display: block;
-	flex: 1;
-	margin: auto !important;
-	text-align: center;
-	font-size: 34upx;
-}
-
-/* ==================
-         导航栏
- ==================== */
-
-.nav {
-	white-space: nowrap;
-}
-
-::-webkit-scrollbar {
-	display: none;
-}
-
-.nav .cu-item {
-	height: 90upx;
-	display: inline-block;
-	line-height: 90upx;
-	margin: 0 10upx;
-	padding: 0 20upx;
-}
-
-.nav .cu-item.cur {
-	border-bottom: 4upx solid;
-}
-
-/* ==================
-         时间轴
- ==================== */
-
-.cu-timeline {
-	display: block;
-	background-color: #ffffff;
-}
-
-.cu-timeline .cu-time {
-	width: 120upx;
-	text-align: center;
-	padding: 20upx 0;
-	font-size: 26upx;
-	color: #888;
-	display: block;
-}
-
-.cu-timeline>.cu-item {
-	padding: 30upx 30upx 30upx 120upx;
-	position: relative;
-	display: block;
-	z-index: 0;
-}
-
-.cu-timeline>.cu-item:not([class*="text-"]) {
-	color: #ccc;
-}
-
-.cu-timeline>.cu-item::after {
-	content: "";
-	display: block;
-	position: absolute;
-	width: 1upx;
-	background-color: #ddd;
-	left: 60upx;
-	height: 100%;
-	top: 0;
-	z-index: 8;
-}
-
-.cu-timeline>.cu-item::before {
-	font-family: "cuIcon";
-	display: block;
-	position: absolute;
-	top: 36upx;
-	z-index: 9;
-	background-color: #ffffff;
-	width: 50upx;
-	height: 50upx;
-	text-align: center;
-	border: none;
-	line-height: 50upx;
-	left: 36upx;
-}
-
-.cu-timeline>.cu-item:not([class*="cuIcon-"])::before {
-	content: "\e763";
-}
-
-.cu-timeline>.cu-item[class*="cuIcon-"]::before {
-	background-color: #ffffff;
-	width: 50upx;
-	height: 50upx;
-	text-align: center;
-	border: none;
-	line-height: 50upx;
-	left: 36upx;
-}
-
-.cu-timeline>.cu-item>.content {
-	padding: 30upx;
-	border-radius: 6upx;
-	display: block;
-	line-height: 1.6;
-}
-
-.cu-timeline>.cu-item>.content:not([class*="bg-"]) {
-	background-color: #f1f1f1;
-	color: #333333;
-}
-
-.cu-timeline>.cu-item>.content+.content {
-	margin-top: 20upx;
-}
-
-/* ==================
-         聊天
- ==================== */
-
-.cu-chat {
-	display: flex;
-	flex-direction: column;
-}
-
-.cu-chat .cu-item {
-	display: flex;
-	padding: 30upx 30upx 70upx;
-	position: relative;
-}
-
-.cu-chat .cu-item>.cu-avatar {
-	width: 80upx;
-	height: 80upx;
-}
-
-.cu-chat .cu-item>.main {
-	max-width: calc(100% - 260upx);
-	margin: 0 40upx;
-	display: flex;
-	align-items: center;
-}
-
-.cu-chat .cu-item>image {
-	height: 320upx;
-}
-
-.cu-chat .cu-item>.main .content {
-	padding: 20upx;
-	border-radius: 6upx;
-	display: inline-flex;
-	max-width: 100%;
-	align-items: center;
-	font-size: 30upx;
-	position: relative;
-	min-height: 80upx;
-	line-height: 40upx;
-	text-align: left;
-}
-
-.cu-chat .cu-item>.main .content:not([class*="bg-"]) {
-	background-color: #ffffff;
-	color: #333333;
-}
-
-.cu-chat .cu-item .date {
-	position: absolute;
-	font-size: 24upx;
-	color: #8799a3;
-	width: calc(100% - 320upx);
-	bottom: 20upx;
-	left: 160upx;
-}
-
-.cu-chat .cu-item .action {
-	padding: 0 30upx;
-	display: flex;
-	align-items: center;
-}
-
-.cu-chat .cu-item>.main .content::after {
-	content: "";
-	top: 27upx;
-	transform: rotate(45deg);
-	position: absolute;
-	z-index: 100;
-	display: inline-block;
-	overflow: hidden;
-	width: 24upx;
-	height: 24upx;
-	left: -12upx;
-	right: initial;
-	background-color: inherit;
-}
-
-.cu-chat .cu-item.self>.main .content::after {
-	left: auto;
-	right: -12upx;
-}
-
-.cu-chat .cu-item>.main .content::before {
-	content: "";
-	top: 30upx;
-	transform: rotate(45deg);
-	position: absolute;
-	z-index: -1;
-	display: inline-block;
-	overflow: hidden;
-	width: 24upx;
-	height: 24upx;
-	left: -12upx;
-	right: initial;
-	background-color: inherit;
-	filter: blur(5upx);
-	opacity: 0.3;
-}
-
-.cu-chat .cu-item>.main .content:not([class*="bg-"])::before {
-	background-color: #333333;
-	opacity: 0.1;
-}
-
-.cu-chat .cu-item.self>.main .content::before {
-	left: auto;
-	right: -12upx;
-}
-
-.cu-chat .cu-item.self {
-	justify-content: flex-end;
-	text-align: right;
-}
-
-.cu-chat .cu-info {
-	display: inline-block;
-	margin: 20upx auto;
-	font-size: 24upx;
-	padding: 8upx 12upx;
-	background-color: rgba(0, 0, 0, 0.2);
-	border-radius: 6upx;
-	color: #ffffff;
-	max-width: 400upx;
-	line-height: 1.4;
-}
-
-/* ==================
-         卡片
- ==================== */
-
-.cu-card {
-	display: block;
-	overflow: hidden;
-}
-
-.cu-card>.cu-item {
-	display: block;
-	background-color: #ffffff;
-	overflow: hidden;
-	border-radius: 10upx;
-	margin: 30upx;
-}
-
-.cu-card>.cu-item.shadow-blur {
-	overflow: initial;
-}
-
-.cu-card.no-card>.cu-item {
-	margin: 0upx;
-	border-radius: 0upx;
-}
-
-.cu-card .grid.grid-square {
-	margin-bottom: -20upx;
-}
-
-.cu-card.case .image {
-	position: relative;
-}
-
-.cu-card.case .image image {
-	width: 100%;
-}
-
-.cu-card.case .image .cu-tag {
-	position: absolute;
-	right: 0;
-	top: 0;
-}
-
-.cu-card.case .image .cu-bar {
-	position: absolute;
-	bottom: 0;
-	width: 100%;
-	background-color: transparent;
-	padding: 0upx 30upx;
-}
-
-.cu-card.case.no-card .image {
-	margin: 30upx 30upx 0;
-	overflow: hidden;
-	border-radius: 10upx;
-}
-
-.cu-card.dynamic {
-	display: block;
-}
-
-.cu-card.dynamic>.cu-item {
-	display: block;
-	background-color: #ffffff;
-	overflow: hidden;
-}
-
-.cu-card.dynamic>.cu-item>.text-content {
-	padding: 0 30upx 0;
-	max-height: 6.4em;
-	overflow: hidden;
-	font-size: 30upx;
-	margin-bottom: 20upx;
-}
-
-.cu-card.dynamic>.cu-item .square-img {
-	width: 100%;
-	height: 200upx;
-	border-radius: 6upx;
-}
-
-.cu-card.dynamic>.cu-item .only-img {
-	width: 100%;
-	height: 320upx;
-	border-radius: 6upx;
-}
-
-/* card.dynamic>.cu-item .comment {
-  padding: 20upx;
-  background-color: #f1f1f1;
-  margin: 0 30upx 30upx;
-  border-radius: 6upx;
-} */
-
-.cu-card.article {
-	display: block;
-}
-
-.cu-card.article>.cu-item {
-	padding-bottom: 30upx;
-}
-
-.cu-card.article>.cu-item .title {
-	font-size: 30upx;
-	font-weight: 900;
-	color: #333333;
-	line-height: 100upx;
-	padding: 0 30upx;
-}
-
-.cu-card.article>.cu-item .content {
-	display: flex;
-	padding: 0 30upx;
-}
-
-.cu-card.article>.cu-item .content>image {
-	width: 240upx;
-	height: 6.4em;
-	margin-right: 20upx;
-	border-radius: 6upx;
-}
-
-.cu-card.article>.cu-item .content .desc {
-	flex: 1;
-	display: flex;
-	flex-direction: column;
-	justify-content: space-between;
-}
-
-.cu-card.article>.cu-item .content .text-content {
-	font-size: 28upx;
-	color: #888;
-	height: 4.8em;
-	overflow: hidden;
-}
-
-/* ==================
-         表单
- ==================== */
-
-.cu-form-group {
-	background-color: #ffffff;
-	padding: 1upx 30upx;
-	display: flex;
-	align-items: center;
-	min-height: 100upx;
-	justify-content: space-between;
-}
-
-.cu-form-group+.cu-form-group {
-	border-top: 1upx solid #eee;
-}
-
-.cu-form-group .title {
-	text-align: justify;
-	padding-right: 30upx;
-	font-size: 30upx;
-	position: relative;
-	height: 60upx;
-	line-height: 60upx;
-}
-
-.cu-form-group input {
-	flex: 1;
-	font-size: 30upx;
-	color: #555;
-	padding-right: 20upx;
-}
-
-.cu-form-group>text[class*="cuIcon-"] {
-	font-size: 36upx;
-	padding: 0;
-	box-sizing: border-box;
-}
-
-.cu-form-group textarea {
-	margin: 32upx 0 30upx;
-	height: 4.6em;
-	width: 100%;
-	line-height: 1.2em;
-	flex: 1;
-	font-size: 28upx;
-	padding: 0;
-}
-
-.cu-form-group.align-start .title {
-	height: 1em;
-	margin-top: 32upx;
-	line-height: 1em;
-}
-
-.cu-form-group picker {
-	flex: 1;
-	padding-right: 40upx;
-	overflow: hidden;
-	position: relative;
-}
-
-.cu-form-group picker .picker {
-	line-height: 100upx;
-	font-size: 28upx;
-	text-overflow: ellipsis;
-	white-space: nowrap;
-	overflow: hidden;
-	width: 100%;
-	text-align: right;
-}
-
-.cu-form-group picker::after {
-	font-family: cuIcon;
-	display: block;
-	content: "\e6a3";
-	position: absolute;
-	font-size: 34upx;
-	color: #8799a3;
-	line-height: 100upx;
-	width: 60upx;
-	text-align: center;
-	top: 0;
-	bottom: 0;
-	right: -20upx;
-	margin: auto;
-}
-
-.cu-form-group textarea[disabled],
-.cu-form-group textarea[disabled] .placeholder {
-	color: transparent;
-}
-
-/* ==================
-         模态窗口
- ==================== */
-
-.cu-modal {
-	position: fixed;
-	top: 0;
-	right: 0;
-	bottom: 0;
-	left: 0;
-	z-index: 1110;
-	opacity: 0;
-	outline: 0;
-	text-align: center;
-	-ms-transform: scale(1.185);
-	transform: scale(1.185);
-	backface-visibility: hidden;
-	perspective: 2000upx;
-	background: rgba(0, 0, 0, 0.6);
-	transition: all 0.3s ease-in-out 0s;
-	pointer-events: none;
-}
-
-.cu-modal::before {
-	content: "\200B";
-	display: inline-block;
-	height: 100%;
-	vertical-align: middle;
-}
-
-.cu-modal.show {
-	opacity: 1;
-	transition-duration: 0.3s;
-	-ms-transform: scale(1);
-	transform: scale(1);
-	overflow-x: hidden;
-	overflow-y: auto;
-	pointer-events: auto;
-}
-
-.cu-dialog {
-	position: relative;
-	display: inline-block;
-	vertical-align: middle;
-	margin-left: auto;
-	margin-right: auto;
-	width: 680upx;
-	max-width: 100%;
-	background-color: #f8f8f8;
-	border-radius: 10upx;
-	overflow: hidden;
-}
-
-.cu-modal.bottom-modal::before {
-	vertical-align: bottom;
-}
-
-.cu-modal.bottom-modal .cu-dialog {
-	width: 100%;
-	border-radius: 0;
-}
-
-.cu-modal.bottom-modal {
-	margin-bottom: -1000upx;
-}
-
-.cu-modal.bottom-modal.show {
-	margin-bottom: 0;
-}
-
-.cu-modal.drawer-modal {
-	transform: scale(1);
-	display: flex;
-}
-
-.cu-modal.drawer-modal .cu-dialog {
-	height: 100%;
-	min-width: 200upx;
-	border-radius: 0;
-	margin: initial;
-	transition-duration: 0.3s;
-}
-
-.cu-modal.drawer-modal.justify-start .cu-dialog {
-	transform: translateX(-100%);
-}
-
-.cu-modal.drawer-modal.justify-end .cu-dialog {
-	transform: translateX(100%);
-}
-
-.cu-modal.drawer-modal.show .cu-dialog {
-	transform: translateX(0%);
-}
-.cu-modal .cu-dialog>.cu-bar:first-child .action{
-  min-width: 100rpx;
-  margin-right: 0;
-  min-height: 100rpx;
-}
-/* ==================
-         轮播
- ==================== */
-swiper .a-swiper-dot {
-	display: inline-block;
-	width: 16upx;
-	height: 16upx;
-	background: rgba(0, 0, 0, .3);
-	border-radius: 50%;
-	vertical-align: middle;
-}
-
-swiper[class*="-dot"] .wx-swiper-dots,
-swiper[class*="-dot"] .a-swiper-dots,
-swiper[class*="-dot"] .uni-swiper-dots {
-	display: flex;
-	align-items: center;
-	width: 100%;
-	justify-content: center;
-}
-
-swiper.square-dot .wx-swiper-dot,
-swiper.square-dot .a-swiper-dot,
-swiper.square-dot .uni-swiper-dot {
-	background-color: #ffffff;
-	opacity: 0.4;
-	width: 10upx;
-	height: 10upx;
-	border-radius: 20upx;
-	margin: 0 8upx !important;
-}
-
-swiper.square-dot .wx-swiper-dot.wx-swiper-dot-active,
-swiper.square-dot .a-swiper-dot.a-swiper-dot-active,
-swiper.square-dot .uni-swiper-dot.uni-swiper-dot-active {
-	opacity: 1;
-	width: 30upx;
-}
-
-swiper.round-dot .wx-swiper-dot,
-swiper.round-dot .a-swiper-dot,
-swiper.round-dot .uni-swiper-dot {
-	width: 10upx;
-	height: 10upx;
-	position: relative;
-	margin: 4upx 8upx !important;
-}
-
-swiper.round-dot .wx-swiper-dot.wx-swiper-dot-active::after,
-swiper.round-dot .a-swiper-dot.a-swiper-dot-active::after,
-swiper.round-dot .uni-swiper-dot.uni-swiper-dot-active::after {
-	content: "";
-	position: absolute;
-	width: 10upx;
-	height: 10upx;
-	top: 0upx;
-	left: 0upx;
-	right: 0;
-	bottom: 0;
-	margin: auto;
-	background-color: #ffffff;
-	border-radius: 20upx;
-}
-
-swiper.round-dot .wx-swiper-dot.wx-swiper-dot-active,
-swiper.round-dot .a-swiper-dot.a-swiper-dot-active,
-swiper.round-dot .uni-swiper-dot.uni-swiper-dot-active {
-	width: 18upx;
-	height: 18upx;
-}
-
-.screen-swiper {
-	min-height: 375upx;
-}
-
-.screen-swiper image,
-.screen-swiper video,
-.swiper-item image,
-.swiper-item video {
-	width: 100%;
-	display: block;
-	height: 100%;
-	margin: 0;
-	pointer-events: none;
-}
-
-.card-swiper {
-	height: 420upx !important;
-}
-
-.card-swiper swiper-item {
-	width: 610upx !important;
-	left: 70upx;
-	box-sizing: border-box;
-	padding: 40upx 0upx 70upx;
-	overflow: initial;
-}
-
-.card-swiper swiper-item .swiper-item {
-	width: 100%;
-	display: block;
-	height: 100%;
-	border-radius: 10upx;
-	transform: scale(0.9);
-	transition: all 0.2s ease-in 0s;
-	overflow: hidden;
-}
-
-.card-swiper swiper-item.cur .swiper-item {
-	transform: none;
-	transition: all 0.2s ease-in 0s;
-}
-
-
-.tower-swiper {
-	height: 420upx;
-	position: relative;
-	max-width: 750upx;
-	overflow: hidden;
-}
-
-.tower-swiper .tower-item {
-	position: absolute;
-	width: 300upx;
-	height: 380upx;
-	top: 0;
-	bottom: 0;
-	left: 50%;
-	margin: auto;
-	transition: all 0.2s ease-in 0s;
-	opacity: 1;
-}
-
-.tower-swiper .tower-item.none {
-	opacity: 0;
-}
-
-.tower-swiper .tower-item .swiper-item {
-	width: 100%;
-	height: 100%;
-	border-radius: 6upx;
-	overflow: hidden;
-}
-
-/* ==================
-          步骤条
- ==================== */
-
-.cu-steps {
-	display: flex;
-}
-
-scroll-view.cu-steps {
-	display: block;
-	white-space: nowrap;
-}
-
-scroll-view.cu-steps .cu-item {
-	display: inline-block;
-}
-
-.cu-steps .cu-item {
-	flex: 1;
-	text-align: center;
-	position: relative;
-	min-width: 100upx;
-}
-
-.cu-steps .cu-item:not([class*="text-"]) {
-	color: #8799a3;
-}
-
-.cu-steps .cu-item [class*="cuIcon-"],
-.cu-steps .cu-item .num {
-	display: block;
-	font-size: 40upx;
-	line-height: 80upx;
-}
-
-.cu-steps .cu-item::before,
-.cu-steps .cu-item::after,
-.cu-steps.steps-arrow .cu-item::before,
-.cu-steps.steps-arrow .cu-item::after {
-	content: "";
-	display: block;
-	position: absolute;
-	height: 0px;
-	width: calc(100% - 80upx);
-	border-bottom: 1px solid #ccc;
-	left: calc(0px - (100% - 80upx) / 2);
-	top: 40upx;
-	z-index: 0;
-}
-
-.cu-steps.steps-arrow .cu-item::before,
-.cu-steps.steps-arrow .cu-item::after {
-	content: "\e6a3";
-	font-family: 'cuIcon';
-	height: 30upx;
-	border-bottom-width: 0px;
-	line-height: 30upx;
-	top: 0;
-	bottom: 0;
-	margin: auto;
-	color: #ccc;
-}
-
-.cu-steps.steps-bottom .cu-item::before,
-.cu-steps.steps-bottom .cu-item::after {
-	bottom: 40upx;
-	top: initial;
-}
-
-.cu-steps .cu-item::after {
-	border-bottom: 1px solid currentColor;
-	width: 0px;
-	transition: all 0.3s ease-in-out 0s;
-}
-
-.cu-steps .cu-item[class*="text-"]::after {
-	width: calc(100% - 80upx);
-	color: currentColor;
-}
-
-.cu-steps .cu-item:first-child::before,
-.cu-steps .cu-item:first-child::after {
-	display: none;
-}
-
-.cu-steps .cu-item .num {
-	width: 40upx;
-	height: 40upx;
-	border-radius: 50%;
-	line-height: 40upx;
-	margin: 20upx auto;
-	font-size: 24upx;
-	border: 1px solid currentColor;
-	position: relative;
-	overflow: hidden;
-}
-
-.cu-steps .cu-item[class*="text-"] .num {
-	background-color: currentColor;
-}
-
-.cu-steps .cu-item .num::before,
-.cu-steps .cu-item .num::after {
-	content: attr(data-index);
-	position: absolute;
-	left: 0;
-	right: 0;
-	top: 0;
-	bottom: 0;
-	margin: auto;
-	transition: all 0.3s ease-in-out 0s;
-	transform: translateY(0upx);
-}
-
-.cu-steps .cu-item[class*="text-"] .num::before {
-	transform: translateY(-40upx);
-	color: #ffffff;
-}
-
-.cu-steps .cu-item .num::after {
-	transform: translateY(40upx);
-	color: #ffffff;
-	transition: all 0.3s ease-in-out 0s;
-}
-
-.cu-steps .cu-item[class*="text-"] .num::after {
-	content: "\e645";
-	font-family: 'cuIcon';
-	color: #ffffff;
-	transform: translateY(0upx);
-}
-
-.cu-steps .cu-item[class*="text-"] .num.err::after {
-	content: "\e646";
-}
-
-/* ==================
-          布局
- ==================== */
-
-/*  -- flex弹性布局 -- */
-
-.flex {
-	display: flex;
-}
-
-.basis-xs {
-	flex-basis: 20%;
-}
-
-.basis-sm {
-	flex-basis: 40%;
-}
-
-.basis-df {
-	flex-basis: 50%;
-}
-
-.basis-lg {
-	flex-basis: 60%;
-}
-
-.basis-xl {
-	flex-basis: 80%;
-}
-
-.flex-sub {
-	flex: 1;
-}
-
-.flex-twice {
-	flex: 2;
-}
-
-.flex-treble {
-	flex: 3;
-}
-
-.flex-direction {
-	flex-direction: column;
-}
-
-.flex-wrap {
-	flex-wrap: wrap;
-}
-
-.align-start {
-	align-items: flex-start;
-}
-
-.align-end {
-	align-items: flex-end;
-}
-
-.align-center {
-	align-items: center;
-}
-
-.align-stretch {
-	align-items: stretch;
-}
-
-.self-start {
-	align-self: flex-start;
-}
-
-.self-center {
-	align-self: flex-center;
-}
-
-.self-end {
-	align-self: flex-end;
-}
-
-.self-stretch {
-	align-self: stretch;
-}
-
-.align-stretch {
-	align-items: stretch;
-}
-
-.justify-start {
-	justify-content: flex-start;
-}
-
-.justify-end {
-	justify-content: flex-end;
-}
-
-.justify-center {
-	justify-content: center;
-}
-
-.justify-between {
-	justify-content: space-between;
-}
-
-.justify-around {
-	justify-content: space-around;
-}
-
-/* grid布局 */
-
-.grid {
-	display: flex;
-	flex-wrap: wrap;
-}
-
-.grid.grid-square {
-	overflow: hidden;
-}
-
-.grid.grid-square .cu-tag {
-	position: absolute;
-	right: 0;
-	top: 0;
-	border-bottom-left-radius: 6upx;
-	padding: 6upx 12upx;
-	height: auto;
-	background-color: rgba(0, 0, 0, 0.5);
-}
-
-.grid.grid-square>view>text[class*="cuIcon-"] {
-	font-size: 52upx;
-	position: absolute;
-	color: #8799a3;
-	margin: auto;
-	top: 0;
-	bottom: 0;
-	left: 0;
-	right: 0;
-	display: flex;
-	justify-content: center;
-	align-items: center;
-	flex-direction: column;
-}
-
-.grid.grid-square>view {
-	margin-right: 20upx;
-	margin-bottom: 20upx;
-	border-radius: 6upx;
-	position: relative;
-	overflow: hidden;
-}
-.grid.grid-square>view.bg-img image {
-	width: 100%;
-	height: 100%;
-	position: absolute;
-}
-.grid.col-1.grid-square>view {
-	padding-bottom: 100%;
-	height: 0;
-	margin-right: 0;
-}
-
-.grid.col-2.grid-square>view {
-	padding-bottom: calc((100% - 20upx)/2);
-	height: 0;
-	width: calc((100% - 20upx)/2);
-}
-
-.grid.col-3.grid-square>view {
-	padding-bottom: calc((100% - 40upx)/3);
-	height: 0;
-	width: calc((100% - 40upx)/3);
-}
-
-.grid.col-4.grid-square>view {
-	padding-bottom: calc((100% - 60upx)/4);
-	height: 0;
-	width: calc((100% - 60upx)/4);
-}
-
-.grid.col-5.grid-square>view {
-	padding-bottom: calc((100% - 80upx)/5);
-	height: 0;
-	width: calc((100% - 80upx)/5);
-}
-
-.grid.col-2.grid-square>view:nth-child(2n),
-.grid.col-3.grid-square>view:nth-child(3n),
-.grid.col-4.grid-square>view:nth-child(4n),
-.grid.col-5.grid-square>view:nth-child(5n) {
-	margin-right: 0;
-}
-
-.grid.col-1>view {
-	width: 100%;
-}
-
-.grid.col-2>view {
-	width: 50%;
-}
-
-.grid.col-3>view {
-	width: 33.33%;
-}
-
-.grid.col-4>view {
-	width: 25%;
-}
-
-.grid.col-5>view {
-	width: 20%;
-}
-
-/*  -- 内外边距 -- */
-
-.margin-0 {
-	margin: 0;
-}
-
-.margin-xs {
-	margin: 10upx;
-}
-
-.margin-sm {
-	margin: 20upx;
-}
-
-.margin {
-	margin: 30upx;
-}
-
-.margin-lg {
-	margin: 40upx;
-}
-
-.margin-xl {
-	margin: 50upx;
-}
-
-.margin-top-xs {
-	margin-top: 10upx;
-}
-
-.margin-top-sm {
-	margin-top: 20upx;
-}
-
-.margin-top {
-	margin-top: 30upx;
-}
-
-.margin-top-lg {
-	margin-top: 40upx;
-}
-
-.margin-top-xl {
-	margin-top: 50upx;
-}
-
-.margin-right-xs {
-	margin-right: 10upx;
-}
-
-.margin-right-sm {
-	margin-right: 20upx;
-}
-
-.margin-right {
-	margin-right: 30upx;
-}
-
-.margin-right-lg {
-	margin-right: 40upx;
-}
-
-.margin-right-xl {
-	margin-right: 50upx;
-}
-
-.margin-bottom-xs {
-	margin-bottom: 10upx;
-}
-
-.margin-bottom-sm {
-	margin-bottom: 20upx;
-}
-
-.margin-bottom {
-	margin-bottom: 30upx;
-}
-
-.margin-bottom-lg {
-	margin-bottom: 40upx;
-}
-
-.margin-bottom-xl {
-	margin-bottom: 50upx;
-}
-
-.margin-left-xs {
-	margin-left: 10upx;
-}
-
-.margin-left-10 {
-	margin-left: 10upx;
-}
-
-.margin-left-sm {
-	margin-left: 20upx;
-}
-
-.margin-left-20 {
-	margin-left: 20upx;
-}
-
-.margin-left {
-	margin-left: 30upx;
-}
-
-.margin-left-30 {
-	margin-left: 30upx;
-}
-
-.margin-left-lg {
-	margin-left: 40upx;
-}
-
-.margin-left-40 {
-	margin-left: 40upx;
-}
-
-.margin-left-xl {
-	margin-left: 50upx;
-}
-
-.margin-left-50 {
-	margin-left: 50upx;
-}
-
-.margin-left-60 {
-	margin-left: 60upx;
-}
-
-.margin-left-80 {
-	margin-left: 80upx;
-}
-
-.margin-left-100 {
-	margin-left: 100upx;
-}
-
-.margin-lr-xs {
-	margin-left: 10upx;
-	margin-right: 10upx;
-}
-
-.margin-lr-sm {
-	margin-left: 20upx;
-	margin-right: 20upx;
-}
-
-.margin-lr {
-	margin-left: 30upx;
-	margin-right: 30upx;
-}
-
-.margin-lr-lg {
-	margin-left: 40upx;
-	margin-right: 40upx;
-}
-
-.margin-lr-xl {
-	margin-left: 50upx;
-	margin-right: 50upx;
-}
-
-.margin-tb-xs {
-	margin-top: 10upx;
-	margin-bottom: 10upx;
-}
-
-.margin-tb-sm {
-	margin-top: 20upx;
-	margin-bottom: 20upx;
-}
-
-.margin-tb {
-	margin-top: 30upx;
-	margin-bottom: 30upx;
-}
-
-.margin-tb-lg {
-	margin-top: 40upx;
-	margin-bottom: 40upx;
-}
-
-.margin-tb-xl {
-	margin-top: 50upx;
-	margin-bottom: 50upx;
-}
-
-.padding-0 {
-	padding: 0;
-}
-
-.padding-xs {
-	padding: 10upx;
-}
-
-.padding-sm {
-	padding: 20upx;
-}
-
-.padding {
-	padding: 30upx;
-}
-
-.padding-lg {
-	padding: 40upx;
-}
-
-.padding-xl {
-	padding: 50upx;
-}
-
-.padding-top-xs {
-	padding-top: 10upx;
-}
-
-.padding-top-sm {
-	padding-top: 20upx;
-}
-
-.padding-top {
-	padding-top: 30upx;
-}
-
-.padding-top-lg {
-	padding-top: 40upx;
-}
-
-.padding-top-xl {
-	padding-top: 50upx;
-}
-
-.padding-right-xs {
-	padding-right: 10upx;
-}
-
-.padding-right-sm {
-	padding-right: 20upx;
-}
-
-.padding-right {
-	padding-right: 30upx;
-}
-
-.padding-right-lg {
-	padding-right: 40upx;
-}
-
-.padding-right-xl {
-	padding-right: 50upx;
-}
-
-.padding-bottom-xs {
-	padding-bottom: 10upx;
-}
-
-.padding-bottom-sm {
-	padding-bottom: 20upx;
-}
-
-.padding-bottom {
-	padding-bottom: 30upx;
-}
-
-.padding-bottom-lg {
-	padding-bottom: 40upx;
-}
-
-.padding-bottom-xl {
-	padding-bottom: 50upx;
-}
-
-.padding-left-xs {
-	padding-left: 10upx;
-}
-
-.padding-left-sm {
-	padding-left: 20upx;
-}
-
-.padding-left {
-	padding-left: 30upx;
-}
-
-.padding-left-lg {
-	padding-left: 40upx;
-}
-
-.padding-left-xl {
-	padding-left: 50upx;
-}
-
-.padding-lr-xs {
-	padding-left: 10upx;
-	padding-right: 10upx;
-}
-
-.padding-lr-sm {
-	padding-left: 20upx;
-	padding-right: 20upx;
-}
-
-.padding-lr {
-	padding-left: 30upx;
-	padding-right: 30upx;
-}
-
-.padding-lr-lg {
-	padding-left: 40upx;
-	padding-right: 40upx;
-}
-
-.padding-lr-xl {
-	padding-left: 50upx;
-	padding-right: 50upx;
-}
-
-.padding-tb-xs {
-	padding-top: 10upx;
-	padding-bottom: 10upx;
-}
-
-.padding-tb-sm {
-	padding-top: 20upx;
-	padding-bottom: 20upx;
-}
-
-.padding-tb {
-	padding-top: 30upx;
-	padding-bottom: 30upx;
-}
-
-.padding-tb-lg {
-	padding-top: 40upx;
-	padding-bottom: 40upx;
-}
-
-.padding-tb-xl {
-	padding-top: 50upx;
-	padding-bottom: 50upx;
-}
-
-/* -- 浮动 --  */
-
-.cf::after,
-.cf::before {
-	content: " ";
-	display: table;
-}
-
-.cf::after {
-	clear: both;
-}
-
-.fl {
-	float: left;
-}
-
-.fr {
-	float: right;
-}
-
-/* ==================
-          背景
- ==================== */
-
-.line-red::after,
-.lines-red::after {
-	border-color: #e54d42;
-}
-
-.line-orange::after,
-.lines-orange::after {
-	border-color: #f37b1d;
-}
-
-.line-yellow::after,
-.lines-yellow::after {
-	border-color: #fbbd08;
-}
-
-.line-olive::after,
-.lines-olive::after {
-	border-color: #8dc63f;
-}
-
-.line-green::after,
-.lines-green::after {
-	border-color: #39b54a;
-}
-
-.line-cyan::after,
-.lines-cyan::after {
-	border-color: #1cbbb4;
-}
-
-.line-blue::after,
-.lines-blue::after {
-	border-color: #0081ff;
-}
-
-.line-purple::after,
-.lines-purple::after {
-	border-color: #6739b6;
-}
-
-.line-mauve::after,
-.lines-mauve::after {
-	border-color: #9c26b0;
-}
-
-.line-pink::after,
-.lines-pink::after {
-	border-color: #e03997;
-}
-
-.line-brown::after,
-.lines-brown::after {
-	border-color: #a5673f;
-}
-
-.line-grey::after,
-.lines-grey::after {
-	border-color: #8799a3;
-}
-
-.line-gray::after,
-.lines-gray::after {
-	border-color: #aaaaaa;
-}
-
-.line-black::after,
-.lines-black::after {
-	border-color: #333333;
-}
-
-.line-white::after,
-.lines-white::after {
-	border-color: #ffffff;
-}
-
-.bg-red {
-	background-color: #e54d42;
-	color: #ffffff;
-}
-
-.bg-orange {
-	background-color: #f37b1d;
-	color: #ffffff;
-}
-
-.bg-yellow {
-	background-color: #fbbd08;
-	color: #333333;
-}
-
-.bg-olive {
-	background-color: #8dc63f;
-	color: #ffffff;
-}
-
-.bg-green {
-	background-color: #39b54a;
-	color: #ffffff;
-}
-
-.bg-cyan {
-	background-color: #1cbbb4;
-	color: #ffffff;
-}
-
-.bg-blue {
-	background-color: #0081ff;
-	color: #ffffff;
-}
-
-.bg-purple {
-	background-color: #6739b6;
-	color: #ffffff;
-}
-
-.bg-mauve {
-	background-color: #9c26b0;
-	color: #ffffff;
-}
-
-.bg-pink {
-	background-color: #e03997;
-	color: #ffffff;
-}
-
-.bg-brown {
-	background-color: #a5673f;
-	color: #ffffff;
-}
-
-.bg-grey {
-	background-color: #8799a3;
-	color: #ffffff;
-}
-
-.bg-gray {
-	background-color: #f0f0f0;
-	color: #333333;
-}
-
-.bg-black {
-	background-color: #333333;
-	color: #ffffff;
-}
-
-.bg-white {
-	background-color: #ffffff;
-	color: #666666;
-}
-
-.bg-shadeTop {
-	background-image: linear-gradient(rgba(0, 0, 0, 1), rgba(0, 0, 0, 0.01));
-	color: #ffffff;
-}
-
-.bg-shadeBottom {
-	background-image: linear-gradient(rgba(0, 0, 0, 0.01), rgba(0, 0, 0, 1));
-	color: #ffffff;
-}
-
-.bg-red.light {
-	color: #e54d42;
-	background-color: #fadbd9;
-}
-
-.bg-orange.light {
-	color: #f37b1d;
-	background-color: #fde6d2;
-}
-
-.bg-yellow.light {
-	color: #fbbd08;
-	background-color: #fef2ced2;
-}
-
-.bg-olive.light {
-	color: #8dc63f;
-	background-color: #e8f4d9;
-}
-
-.bg-green.light {
-	color: #39b54a;
-	background-color: #d7f0dbff;
-}
-
-.bg-cyan.light {
-	color: #1cbbb4;
-	background-color: #d2f1f0;
-}
-
-.bg-blue.light {
-	color: #0081ff;
-	background-color: #cce6ff;
-}
-
-.bg-purple.light {
-	color: #6739b6;
-	background-color: #e1d7f0;
-}
-
-.bg-mauve.light {
-	color: #9c26b0;
-	background-color: #ebd4ef;
-}
-
-.bg-pink.light {
-	color: #e03997;
-	background-color: #f9d7ea;
-}
-
-.bg-brown.light {
-	color: #a5673f;
-	background-color: #ede1d9;
-}
-
-.bg-grey.light {
-	color: #8799a3;
-	background-color: #e7ebed;
-}
-
-.bg-gradual-red {
-	background-image: linear-gradient(45deg, #f43f3b, #ec008c);
-	color: #ffffff;
-}
-
-.bg-gradual-orange {
-	background-image: linear-gradient(45deg, #ff9700, #ed1c24);
-	color: #ffffff;
-}
-
-.bg-gradual-green {
-	background-image: linear-gradient(45deg, #39b54a, #8dc63f);
-	color: #ffffff;
-}
-
-.bg-gradual-purple {
-	background-image: linear-gradient(45deg, #9000ff, #5e00ff);
-	color: #ffffff;
-}
-
-.bg-gradual-pink {
-	background-image: linear-gradient(45deg, #ec008c, #6739b6);
-	color: #ffffff;
-}
-
-.bg-gradual-blue {
-	background-image: linear-gradient(45deg, #0081ff, #1cbbb4);
-	color: #ffffff;
-}
-
-.shadow[class*="-red"] {
-	box-shadow: 6upx 6upx 8upx rgba(204, 69, 59, 0.2);
-}
-
-.shadow[class*="-orange"] {
-	box-shadow: 6upx 6upx 8upx rgba(217, 109, 26, 0.2);
-}
-
-.shadow[class*="-yellow"] {
-	box-shadow: 6upx 6upx 8upx rgba(224, 170, 7, 0.2);
-}
-
-.shadow[class*="-olive"] {
-	box-shadow: 6upx 6upx 8upx rgba(124, 173, 55, 0.2);
-}
-
-.shadow[class*="-green"] {
-	box-shadow: 6upx 6upx 8upx rgba(48, 156, 63, 0.2);
-}
-
-.shadow[class*="-cyan"] {
-	box-shadow: 6upx 6upx 8upx rgba(28, 187, 180, 0.2);
-}
-
-.shadow[class*="-blue"] {
-	box-shadow: 6upx 6upx 8upx rgba(0, 102, 204, 0.2);
-}
-
-.shadow[class*="-purple"] {
-	box-shadow: 6upx 6upx 8upx rgba(88, 48, 156, 0.2);
-}
-
-.shadow[class*="-mauve"] {
-	box-shadow: 6upx 6upx 8upx rgba(133, 33, 150, 0.2);
-}
-
-.shadow[class*="-pink"] {
-	box-shadow: 6upx 6upx 8upx rgba(199, 50, 134, 0.2);
-}
-
-.shadow[class*="-brown"] {
-	box-shadow: 6upx 6upx 8upx rgba(140, 88, 53, 0.2);
-}
-
-.shadow[class*="-grey"] {
-	box-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2);
-}
-
-.shadow[class*="-gray"] {
-	box-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2);
-}
-
-.shadow[class*="-black"] {
-	box-shadow: 6upx 6upx 8upx rgba(26, 26, 26, 0.2);
-}
-
-.shadow[class*="-white"] {
-	box-shadow: 6upx 6upx 8upx rgba(26, 26, 26, 0.2);
-}
-
-.text-shadow[class*="-red"] {
-	text-shadow: 6upx 6upx 8upx rgba(204, 69, 59, 0.2);
-}
-
-.text-shadow[class*="-orange"] {
-	text-shadow: 6upx 6upx 8upx rgba(217, 109, 26, 0.2);
-}
-
-.text-shadow[class*="-yellow"] {
-	text-shadow: 6upx 6upx 8upx rgba(224, 170, 7, 0.2);
-}
-
-.text-shadow[class*="-olive"] {
-	text-shadow: 6upx 6upx 8upx rgba(124, 173, 55, 0.2);
-}
-
-.text-shadow[class*="-green"] {
-	text-shadow: 6upx 6upx 8upx rgba(48, 156, 63, 0.2);
-}
-
-.text-shadow[class*="-cyan"] {
-	text-shadow: 6upx 6upx 8upx rgba(28, 187, 180, 0.2);
-}
-
-.text-shadow[class*="-blue"] {
-	text-shadow: 6upx 6upx 8upx rgba(0, 102, 204, 0.2);
-}
-
-.text-shadow[class*="-purple"] {
-	text-shadow: 6upx 6upx 8upx rgba(88, 48, 156, 0.2);
-}
-
-.text-shadow[class*="-mauve"] {
-	text-shadow: 6upx 6upx 8upx rgba(133, 33, 150, 0.2);
-}
-
-.text-shadow[class*="-pink"] {
-	text-shadow: 6upx 6upx 8upx rgba(199, 50, 134, 0.2);
-}
-
-.text-shadow[class*="-brown"] {
-	text-shadow: 6upx 6upx 8upx rgba(140, 88, 53, 0.2);
-}
-
-.text-shadow[class*="-grey"] {
-	text-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2);
-}
-
-.text-shadow[class*="-gray"] {
-	text-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2);
-}
-
-.text-shadow[class*="-black"] {
-	text-shadow: 6upx 6upx 8upx rgba(26, 26, 26, 0.2);
-}
-
-.bg-img {
-	background-size: cover;
-	background-position: center;
-	background-repeat: no-repeat;
-}
-
-.bg-mask {
-	background-color: #333333;
-	position: relative;
-}
-
-.bg-mask::after {
-	content: "";
-	border-radius: inherit;
-	width: 100%;
-	height: 100%;
-	display: block;
-	background-color: rgba(0, 0, 0, 0.4);
-	position: absolute;
-	left: 0;
-	right: 0;
-	bottom: 0;
-	top: 0;
-}
-
-.bg-mask view,
-.bg-mask cover-view {
-	z-index: 5;
-	position: relative;
-}
-
-.bg-video {
-	position: relative;
-}
-
-.bg-video video {
-	display: block;
-	height: 100%;
-	width: 100%;
-	-o-object-fit: cover;
-	object-fit: cover;
-	position: absolute;
-	top: 0;
-	z-index: 0;
-	pointer-events: none;
-}
-
-/* ==================
-          文本
- ==================== */
-
-.text-xs {
-	font-size: 20upx;
-}
-
-.text-sm {
-	font-size: 24upx;
-}
-
-.text-df {
-	font-size: 28upx;
-}
-
-.text-30 {
-	font-size: 30upx;
-}
-
-.text-lg {
-	font-size: 32upx;
-}
-
-.text-xl {
-	font-size: 36upx;
-}
-
-.text-xxl {
-	font-size: 44upx;
-}
-
-.text-sl {
-	font-size: 80upx;
-}
-
-.text-xsl {
-	font-size: 120upx;
-}
-
-.text-Abc {
-	text-transform: Capitalize;
-}
-
-.text-ABC {
-	text-transform: Uppercase;
-}
-
-.text-abc {
-	text-transform: Lowercase;
-}
-
-.text-price::before {
-	content: "¥";
-	font-size: 80%;
-	margin-right: 4upx;
-}
-
-.text-cut {
-	text-overflow: ellipsis;
-	white-space: nowrap;
-	overflow: hidden;
-}
-
-.text-normal {
-	font-weight: normal;
-}
-
-.text-bold {
-	font-weight: bold;
-}
-
-.text-boldest {
-	font-weight: 1000;
-}
-
-.text-center {
-	text-align: center;
-}
-
-.text-content {
-	line-height: 1.6;
-}
-
-.text-left {
-	text-align: left;
-}
-
-.text-right {
-	text-align: right;
-}
-
-.text-red,
-.line-red,
-.lines-red {
-	color: #e54d42;
-}
-
-.text-orange,
-.line-orange,
-.lines-orange {
-	color: #f37b1d;
-}
-
-.text-yellow,
-.line-yellow,
-.lines-yellow {
-	color: #fbbd08;
-}
-
-.text-olive,
-.line-olive,
-.lines-olive {
-	color: #8dc63f;
-}
-
-.text-green,
-.line-green,
-.lines-green {
-	color: #39b54a;
-}
-
-.text-cyan,
-.line-cyan,
-.lines-cyan {
-	color: #1cbbb4;
-}
-
-.text-blue,
-.line-blue,
-.lines-blue {
-	color: #0081ff;
-}
-
-.text-purple,
-.line-purple,
-.lines-purple {
-	color: #6739b6;
-}
-
-.text-mauve,
-.line-mauve,
-.lines-mauve {
-	color: #9c26b0;
-}
-
-.text-pink,
-.line-pink,
-.lines-pink {
-	color: #e03997;
-}
-
-.text-brown,
-.line-brown,
-.lines-brown {
-	color: #a5673f;
-}
-
-.text-grey,
-.line-grey,
-.lines-grey {
-	color: #8799a3;
-}
-
-.text-gray,
-.line-gray,
-.lines-gray {
-	color: #aaaaaa;
-}
-
-.text-black,
-.line-black,
-.lines-black {
-	color: #333333;
-}
-
-.text-white,
-.line-white,
-.lines-white {
-	color: #ffffff;
-}
-
-
-
-
-.relative{
-	position: relative;
-}
-
-.center{
-	display: flex;  
-	align-items: center; /* 垂直居中 */  
-	justify-content: center; /* 水平居中,如果需要的话 */    
-}

Разница между файлами не показана из-за своего большого размера
+ 0 - 3
chexnet-master-MP/style/style.scss


+ 2 - 0
chexnet-master-service/.gitattributes

@@ -0,0 +1,2 @@
+/mvnw text eol=lf
+*.cmd text eol=crlf

+ 33 - 0
chexnet-master-service/.gitignore

@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/

+ 1 - 0
chexnet-master-service/chexnet-master-img-api.ini

@@ -0,0 +1 @@
+http://[240e:460:64:6c6:83da:f61d:3179:23f9]:12315/chexnet-master/processImg

+ 149 - 0
chexnet-master-service/mvnw.cmd

@@ -0,0 +1,149 @@
+<# : batch portion
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements.  See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership.  The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License.  You may obtain a copy of the License at
+@REM
+@REM    http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied.  See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Apache Maven Wrapper startup batch script, version 3.3.2
+@REM
+@REM Optional ENV vars
+@REM   MVNW_REPOURL - repo url base for downloading maven distribution
+@REM   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
+@REM   MVNW_VERBOSE - true: enable verbose log; others: silence the output
+@REM ----------------------------------------------------------------------------
+
+@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
+@SET __MVNW_CMD__=
+@SET __MVNW_ERROR__=
+@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
+@SET PSModulePath=
+@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
+  IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
+)
+@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
+@SET __MVNW_PSMODULEP_SAVE=
+@SET __MVNW_ARG0_NAME__=
+@SET MVNW_USERNAME=
+@SET MVNW_PASSWORD=
+@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
+@echo Cannot start maven from wrapper >&2 && exit /b 1
+@GOTO :EOF
+: end batch / begin powershell #>
+
+$ErrorActionPreference = "Stop"
+if ($env:MVNW_VERBOSE -eq "true") {
+  $VerbosePreference = "Continue"
+}
+
+# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
+$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
+if (!$distributionUrl) {
+  Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
+}
+
+switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
+  "maven-mvnd-*" {
+    $USE_MVND = $true
+    $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
+    $MVN_CMD = "mvnd.cmd"
+    break
+  }
+  default {
+    $USE_MVND = $false
+    $MVN_CMD = $script -replace '^mvnw','mvn'
+    break
+  }
+}
+
+# apply MVNW_REPOURL and calculate MAVEN_HOME
+# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
+if ($env:MVNW_REPOURL) {
+  $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
+  $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
+}
+$distributionUrlName = $distributionUrl -replace '^.*/',''
+$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
+$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
+if ($env:MAVEN_USER_HOME) {
+  $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
+}
+$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
+$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
+
+if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
+  Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
+  Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
+  exit $?
+}
+
+if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
+  Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
+}
+
+# prepare tmp dir
+$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
+$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
+$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
+trap {
+  if ($TMP_DOWNLOAD_DIR.Exists) {
+    try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+    catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+  }
+}
+
+New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
+
+# Download and Install Apache Maven
+Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
+Write-Verbose "Downloading from: $distributionUrl"
+Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
+
+$webclient = New-Object System.Net.WebClient
+if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
+  $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
+}
+[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
+
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
+$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
+if ($distributionSha256Sum) {
+  if ($USE_MVND) {
+    Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
+  }
+  Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
+  if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
+    Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
+  }
+}
+
+# unzip and move
+Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
+Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
+try {
+  Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
+} catch {
+  if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
+    Write-Error "fail to move MAVEN_HOME"
+  }
+} finally {
+  try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
+  catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
+}
+
+Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"

+ 105 - 0
chexnet-master-service/pom.xml

@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>3.3.4</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+    <groupId>cn.flea</groupId>
+    <artifactId>chexnet-master</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>chexnet-master</name>
+    <description>chexnet-master</description>
+    <url/>
+    <licenses>
+        <license/>
+    </licenses>
+    <developers>
+        <developer/>
+    </developers>
+    <scm>
+        <connection/>
+        <developerConnection/>
+        <tag/>
+        <url/>
+    </scm>
+    <properties>
+        <java.version>17</java.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+            <version>3.0.3</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.mysql</groupId>
+            <artifactId>mysql-connector-j</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter-test</artifactId>
+            <version>3.0.3</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>0.9.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.xml.bind</groupId>
+            <artifactId>jaxb-api</artifactId>
+            <version>2.3.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.8.8</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>
+                            <groupId>org.projectlombok</groupId>
+                            <artifactId>lombok</artifactId>
+                        </exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 15 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/ChexnetMasterApplication.java

@@ -0,0 +1,15 @@
+package cn.flea.chexnetmaster;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@EnableScheduling
+@SpringBootApplication
+public class ChexnetMasterApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(ChexnetMasterApplication.class, args);
+    }
+
+}

+ 121 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/component/MemoryUserRecordSpace.java

@@ -0,0 +1,121 @@
+package org.lp.medicalai.component;
+
+import org.lp.medicalai.config.XfXhConfig;
+import org.lp.medicalai.dto.InteractMsg;
+import org.lp.medicalai.dto.MsgDTO;
+import org.lp.medicalai.dto.RecordsArray;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+@Component
+public class MemoryUserRecordSpace {
+    @Autowired
+    private XfXhConfig xfXhConfig;
+
+    private final ConcurrentHashMap<Long, RecordsArray> userRecordMap = new ConcurrentHashMap<>();
+
+    public ConcurrentHashMap<Long, RecordsArray> getUserRecordMap() {
+        return userRecordMap;
+    }
+
+    public List<MsgDTO> getAllInteractMsg(Integer id) {
+        RecordsArray recordsArray = userRecordMap.get(id);
+        if (recordsArray == null) {
+            return new ArrayList<>(1);
+        }
+        return recordsArray.getAllInteractMsg();
+    }
+
+    /**
+     * 尝试加锁
+     *
+     * @param id
+     * @return true-加锁成功,false-加锁失败
+     */
+    public boolean tryLock(Integer id) {
+        synchronized (id.toString().intern()) {
+            RecordsArray recordsArray = userRecordMap.get(id);
+            // 如果查不到用户或者没有加锁,则允许操作
+            if (recordsArray == null) {
+                // 用户信息保存到内存
+                RecordsArray newRecordsArray = storeUserRecord(id);
+                // 加锁
+                newRecordsArray.setLock(true);
+                return true;
+            } else if (!recordsArray.isLock()) {
+                // 加锁
+                recordsArray.setLock(true);
+                // 返回
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+
+    /**
+     * 释放锁
+     *
+     * @param id
+     */
+    public void unLock(Integer id) {
+        RecordsArray recordsArray = userRecordMap.get(id);
+        if (recordsArray != null) {
+            recordsArray.setLock(false);
+        }
+    }
+
+    public void storeInteractMsg(Integer id, InteractMsg interactMsg) {
+        RecordsArray recordsArray = userRecordMap.get(id);
+        // 为空说明不存在该用户的记录
+        if (recordsArray == null) {
+            storeUserRecord(id,interactMsg);
+            return;
+        }
+
+        // 不为空的处理
+        recordsArray.addInteractMsg(interactMsg);
+        // 刷新状态为最新
+        recordsArray.setStatus(0);
+    }
+
+    private RecordsArray storeUserRecord(Integer id, InteractMsg interactMsg) {
+        // 判断是否满了
+        while (userRecordMap.size() >= xfXhConfig.getMaxUserCount()) {
+            // 需要移除状态最差(status 最高)的用户
+            int maxStatus = -1;
+            Long userId = 0L;
+            for (Map.Entry<Long, RecordsArray> entry : userRecordMap.entrySet()) {
+                RecordsArray recordsArray = entry.getValue();
+                // 已锁用户不进行处理
+                if (!recordsArray.isLock()) {
+                    // 获取当前用户的状态
+                    int userStatus = recordsArray.getStatus();
+                    if (maxStatus < userStatus) {
+                        maxStatus = userStatus;
+                        userId = entry.getKey();
+                    }
+                }
+            }
+            userRecordMap.remove(userId);
+        }
+        RecordsArray newRecordArray = new RecordsArray(xfXhConfig.getMaxInteractCount());
+        if (interactMsg != null) {
+            newRecordArray.addInteractMsg(interactMsg);
+        }
+        userRecordMap.put(Long.valueOf(id), newRecordArray);
+        return newRecordArray;
+    }
+
+    private RecordsArray storeUserRecord(Integer id){
+        return storeUserRecord(id,null);
+    }
+
+}

+ 45 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/component/ScheduleTask.java

@@ -0,0 +1,45 @@
+package org.lp.medicalai.component;
+
+import org.lp.medicalai.config.XfXhConfig;
+import org.lp.medicalai.dto.RecordsArray;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+
+@EnableScheduling   // 1.开启定时任务
+@EnableAsync        // 2.开启多线程
+@Component
+public class ScheduleTask {
+    @Autowired
+    private MemoryUserRecordSpace memoryUserRecordSpace;
+
+    @Autowired
+    private XfXhConfig xfXhConfig;
+
+    @Scheduled(initialDelayString = "${xfxh.scheduled.updateUserStatusFixedDelay}"
+            ,fixedDelayString  = "${xfxh.scheduled.updateUserStatusFixedDelay}")
+    @Async
+    public void updateUserStatusTask(){
+        ConcurrentHashMap<Long, RecordsArray> userRecordMap = memoryUserRecordSpace.getUserRecordMap();
+        for (Map.Entry<Long, RecordsArray> userRecord : userRecordMap.entrySet()) {
+            RecordsArray recordsArray = userRecord.getValue();
+            // 如果已经加锁,说明正在交互消息中,直接跳过
+            if (recordsArray.isLock()){
+                continue;
+            }
+            // 将状态+1,当超过 xfXhConfig.userRecordMaxStatus 则从空间中移除该用户交互信息
+            recordsArray.setStatus(recordsArray.getStatus()+1);
+            if (recordsArray.getStatus()>xfXhConfig.getUserRecordMaxStatus()){
+                userRecordMap.remove(userRecord.getKey());
+            }
+        }
+    }
+}

+ 143 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/component/XfXhStreamClient.java

@@ -0,0 +1,143 @@
+package org.lp.medicalai.component;
+
+import com.alibaba.fastjson.JSONObject;
+import org.lp.medicalai.config.XfXhConfig;
+import org.lp.medicalai.dto.MsgDTO;
+import org.lp.medicalai.dto.RequestDTO;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+
+@Component
+@Slf4j
+public class XfXhStreamClient {
+    @Autowired
+    private XfXhConfig xfXhConfig;
+
+    @Value("${xfxh.QPS}")
+    private int connectionTokenCount;
+
+    /**
+     * 获取令牌
+     */
+    public static int GET_TOKEN_STATUS = 0;
+    /**
+     * 归还令牌
+     */
+    public static int BACK_TOKEN_STATUS = 1;
+
+    /**
+     * 操作令牌
+     *
+     * @param status 0-获取令牌 1-归还令牌
+     * @return 是否操作成功
+     */
+    public synchronized boolean operateToken(int status) {
+        if (status == GET_TOKEN_STATUS) {
+            // 获取令牌
+            if (connectionTokenCount != 0) {
+                // 说明还有令牌,将令牌数减一
+                connectionTokenCount-=1;
+                return true;
+            }else{
+                return false;
+            }
+        } else {
+            // 放回令牌
+            connectionTokenCount += 1;
+            return true;
+        }
+    }
+
+    /**
+     * 发送消息
+     *
+     * @param uid     每个用户的id,用于区分不同用户
+     * @param msgList 发送给大模型的消息,可以包含上下文内容
+     * @return 获取websocket连接,以便于我们在获取完整大模型回复后手动关闭连接
+     */
+    public WebSocket sendMsg(String uid, List<MsgDTO> msgList, WebSocketListener listener) {
+        // 获取鉴权url
+        String authUrl = this.getAuthUrl();
+        // 鉴权方法生成失败,直接返回 null
+        if (authUrl == null) {
+            return null;
+        }
+        OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
+        // 将 https/http 连接替换为 ws/wss 连接
+        String url = authUrl.replace("http://", "ws://").replace("https://", "wss://");
+        Request request = new Request.Builder().url(url).build();
+        // 建立 wss 连接
+        WebSocket webSocket = okHttpClient.newWebSocket(request, listener);
+        // 组装请求参数
+        RequestDTO requestDTO = getRequestParam(uid, msgList);
+        // 发送请求
+        webSocket.send(JSONObject.toJSONString(requestDTO));
+        return webSocket;
+    }
+
+    /**
+     * 生成鉴权方法,具体实现不用关心,这是讯飞官方定义的鉴权方式
+     *
+     * @return 鉴权访问大模型的路径
+     */
+    public String getAuthUrl() {
+        try {
+            URL url = new URL(xfXhConfig.getHostUrl());
+            // 时间
+            SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
+            format.setTimeZone(TimeZone.getTimeZone("GMT"));
+            String date = format.format(new Date());
+            // 拼接
+            String preStr = "host: " + url.getHost() + "\n" +
+                    "date: " + date + "\n" +
+                    "GET " + url.getPath() + " HTTP/1.1";
+            // SHA256加密
+            Mac mac = Mac.getInstance("hmacsha256");
+            SecretKeySpec spec = new SecretKeySpec(xfXhConfig.getApiSecret().getBytes(StandardCharsets.UTF_8), "hmacsha256");
+            mac.init(spec);
+
+            byte[] hexDigits = mac.doFinal(preStr.getBytes(StandardCharsets.UTF_8));
+            // Base64加密
+            String sha = Base64.getEncoder().encodeToString(hexDigits);
+            // 拼接
+            String authorizationOrigin = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", xfXhConfig.getApiKey(), "hmac-sha256", "host date request-line", sha);
+            // 拼接地址
+            HttpUrl httpUrl = Objects.requireNonNull(HttpUrl.parse("https://" + url.getHost() + url.getPath())).newBuilder().
+                    addQueryParameter("authorization", Base64.getEncoder().encodeToString(authorizationOrigin.getBytes(StandardCharsets.UTF_8))).
+                    addQueryParameter("date", date).
+                    addQueryParameter("host", url.getHost()).
+                    build();
+
+            return httpUrl.toString();
+        } catch (Exception e) {
+            log.error("鉴权方法中发生错误:" + e.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * 获取请求参数
+     *
+     * @param uid     每个用户的id,用于区分不同用户
+     * @param msgList 发送给大模型的消息,可以包含上下文内容
+     * @return 请求DTO,该 DTO 转 json 字符串后生成的格式参考 resources/demo-json/request.json
+     */
+    public RequestDTO getRequestParam(String uid, List<MsgDTO> msgList) {
+        RequestDTO requestDTO = new RequestDTO();
+        requestDTO.setHeader(new RequestDTO.HeaderDTO(xfXhConfig.getAppId(), uid));
+        requestDTO.setParameter(new RequestDTO.ParameterDTO(new RequestDTO.ParameterDTO.ChatDTO(xfXhConfig.getDomain(), xfXhConfig.getTemperature(), xfXhConfig.getMaxTokens())));
+        requestDTO.setPayload(new RequestDTO.PayloadDTO(new RequestDTO.PayloadDTO.MessageDTO(msgList)));
+        return requestDTO;
+    }
+}

+ 19 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/config/WebConfig.java

@@ -0,0 +1,19 @@
+package org.lp.medicalai.config;
+
+import org.lp.medicalai.interceptor.LoginCheckInterceptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class WebConfig implements WebMvcConfigurer {
+
+    @Autowired
+    private LoginCheckInterceptor loginCheckInterceptor;
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/medical-ai/**");
+    }
+}

+ 22 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/config/XfXhConfig.java

@@ -0,0 +1,22 @@
+package org.lp.medicalai.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Data
+@Configuration
+@ConfigurationProperties(prefix = "xfxh")
+public class XfXhConfig {
+    private String hostUrl;
+    private String domain;
+    private Float temperature;
+    private Integer maxTokens;
+    private String appId;
+    private String apiKey;
+    private String apiSecret;
+    private Integer maxInteractCount;
+    private Integer maxUserCount;
+    private Integer userRecordMaxStatus;
+    private Integer maxResponseTime;
+}

+ 123 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/controller/AiController.java

@@ -0,0 +1,123 @@
+package org.lp.medicalai.controller;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONObject;
+import org.lp.medicalai.component.MemoryUserRecordSpace;
+import org.lp.medicalai.component.XfXhStreamClient;
+import org.lp.medicalai.config.XfXhConfig;
+import org.lp.medicalai.dto.InteractMsg;
+import org.lp.medicalai.dto.MsgDTO;
+import org.lp.medicalai.dto.RecordsArray;
+import org.lp.medicalai.listener.XfXhWebSocketListener;
+import okhttp3.WebSocket;
+import org.lp.medicalai.pojo.Result;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+@RestController
+@RequestMapping("/medical-ai")
+public class AiController {
+    @Autowired
+    private XfXhConfig xfXhConfig;
+
+    @Autowired
+    private XfXhStreamClient xfXhStreamClient;
+
+    @Autowired
+    private MemoryUserRecordSpace memoryUserRecordSpace;
+
+    // 使用 id 作为唯一用户的标识(区分不同用户)
+    @GetMapping("/sendQuestion")
+    public Result question(@RequestAttribute("id") Integer id,String question) throws InterruptedException {
+
+        if (StrUtil.isBlank(question)) {
+            return Result.error("NO_QUESTION");//无效问题,请重新输入
+        }
+
+        // 尝试锁定用户
+        if (!memoryUserRecordSpace.tryLock(id)) {
+            return Result.error("WAIT");//正在处理上次问题,请稍后再试
+        }
+
+        // 获取连接令牌
+        if(!xfXhStreamClient.operateToken(XfXhStreamClient.GET_TOKEN_STATUS)){
+            // 释放锁
+            memoryUserRecordSpace.unLock(id);
+            return Result.error("BUSY");//当前大模型连接数过多,请稍后再试
+        }
+
+        MsgDTO msgDTO = MsgDTO.createUserMsg(question);
+        String tip = "你是一位专业且耐心的医生,专注于提供医疗建议。非医疗问题请礼貌拒绝。";
+
+        MsgDTO tipDTO = MsgDTO.createSystemMsg(tip);
+
+        XfXhWebSocketListener listener = new XfXhWebSocketListener();
+
+        // 组装上下文内容发送
+        List<MsgDTO> msgList = memoryUserRecordSpace.getAllInteractMsg(id);
+
+        msgList.add(tipDTO);
+        msgList.add(msgDTO);
+
+        WebSocket webSocket = xfXhStreamClient.sendMsg(UUID.randomUUID().toString().substring(0, 10), msgList, listener);
+        if (webSocket == null) {
+            // 归还令牌
+            xfXhStreamClient.operateToken(XfXhStreamClient.BACK_TOKEN_STATUS);
+            // 释放锁
+            memoryUserRecordSpace.unLock(id);
+            return Result.error("ERROR");//系统内部错误,请联系管理员
+        }
+        try {
+            int count = 0;
+            // 为了避免死循环,设置循环次数来定义超时时长
+            int maxCount = xfXhConfig.getMaxResponseTime() * 5;
+            while (count <= maxCount) {
+                Thread.sleep(200);
+                if (listener.isWsCloseFlag()) {
+                    break;
+                }
+                count++;
+            }
+            if (count > maxCount) {
+                return Result.error("ERROR");//大模型响应超时,请联系管理员
+            }
+            // 将记录添加到 memoryUserRecordSpace
+            String answer = listener.getAnswer().toString();
+            memoryUserRecordSpace.storeInteractMsg(id, new InteractMsg(MsgDTO.createUserMsg(question), MsgDTO.createAssistantMsg(answer)));
+            return Result.success(answer);//相应成功
+        } finally {
+            // 关闭连接
+            webSocket.close(1000, "");
+            // 释放锁
+            memoryUserRecordSpace.unLock(id);
+            // 归还令牌
+            xfXhStreamClient.operateToken(XfXhStreamClient.BACK_TOKEN_STATUS);
+        }
+    }
+
+    // 测试使用,查看内存空间中所有的用户记录信息
+    @GetMapping("/spaceInfo")
+    public List<JSONObject> spaceInfo(@RequestAttribute("id") Integer id){
+        if(id == 1){
+            ConcurrentHashMap<Long, RecordsArray> userRecordMap = memoryUserRecordSpace.getUserRecordMap();
+            ArrayList<JSONObject> infoList = new ArrayList<>(userRecordMap.size());
+            for (Map.Entry<Long, RecordsArray> entry : userRecordMap.entrySet()) {
+                RecordsArray recordsArray = entry.getValue();
+                JSONObject data = new JSONObject();
+                data.put("id",entry.getKey());
+                data.put("allInteractMsg",recordsArray.getAllInteractMsg());
+                data.put("status",recordsArray.getStatus());
+                data.put("lock",recordsArray.isLock());
+                infoList.add(data);
+            }
+            return infoList;
+        }
+        return null;
+    }
+}

+ 42 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/controller/ContentCheck.java

@@ -0,0 +1,42 @@
+package cn.flea.chexnetmaster.controller;
+
+import cn.flea.chexnetmaster.pojo.Result;
+import cn.flea.chexnetmaster.service.ContentCheckService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+@Slf4j
+@RestController
+@RequestMapping("/contentCheck")
+public class ContentCheck {
+
+    @Autowired
+    private ContentCheckService contentCheckService;
+
+    @GetMapping("/textCheck")
+    public Result textCheck(String text, @RequestAttribute("openid") String openid){
+        log.info("待检查文本: " + text);
+
+        Integer res = contentCheckService.textCheck(text,openid);
+        log.info("文本审核结果: " + res);
+
+        if (res == 1) return Result.success("PASS");
+        if (res == 2) return Result.success("NO_PASS");
+
+        return Result.error("文本审核失败");
+    }
+
+    @PostMapping("/imgCheck")
+    public Result imgCheck(MultipartFile img, @RequestAttribute("openid") String openid){
+
+        Integer res = contentCheckService.imgCheck(img,openid);
+        log.info("图片审核结果: " + res);
+
+        if (res == 1) return Result.success("PASS");
+        if (res == 2) return Result.success("NO_PASS");
+
+        return Result.error("图片审核失败");
+    }
+}

+ 43 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/controller/ImgProcessController.java

@@ -0,0 +1,43 @@
+package cn.flea.chexnetmaster.controller;
+
+import cn.flea.chexnetmaster.pojo.Result;
+import cn.flea.chexnetmaster.service.ProcessImgService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+@Slf4j
+@RestController
+@RequestMapping("/chexnet-master")
+@CrossOrigin(origins = "*")
+public class ImgProcessController {
+
+    private String chexnetMasterImgApiUrl = null;
+
+    @Autowired
+    private ProcessImgService processImgService;
+
+    @PostMapping("/processImg")
+    public Result processImg(MultipartFile img) {
+        if (chexnetMasterImgApiUrl == null) {
+            log.error("未设置chexnetMasterImgApiUrl");
+            return Result.error("未设置chexnetMasterImgApiUrl");
+        }
+        return processImgService.processImg(img,chexnetMasterImgApiUrl);
+    }
+
+
+    @PutMapping("/processImg")
+    public Result saveImg(String chexnetMasterImgApiUrl) {
+        if (chexnetMasterImgApiUrl != null || !chexnetMasterImgApiUrl.isEmpty()){
+            this.chexnetMasterImgApiUrl = chexnetMasterImgApiUrl;
+            log.info("更新chexnetMasterImgApiUrl为:{}", chexnetMasterImgApiUrl);
+            return Result.success();
+        }
+        log.error("参数错误");
+        return Result.error("参数错误");
+    }
+
+
+}

+ 73 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/controller/UserController.java

@@ -0,0 +1,73 @@
+package cn.flea.chexnetmaster.controller;
+
+import cn.flea.chexnetmaster.pojo.Result;
+import cn.flea.chexnetmaster.pojo.User;
+import cn.flea.chexnetmaster.service.UserService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+
+@Slf4j
+@RestController
+@CrossOrigin(origins = "*")
+public class UserController {
+
+    @Autowired
+    UserService userService;
+
+    @PostMapping("/user")
+    public Result Login(String code, String type) {
+        log.info("用户登陆,数据: " + "code: " + code + "type" + type);
+        Result res = userService.login(code);
+        log.info("登陆操作完成: " + res);
+        return res;
+    }
+
+    @PutMapping("/user")
+    public Result updateUserById(User user,@RequestAttribute("id") Integer id, String type) {
+        log.info("更新用户,数据: " + "user: " + user + "id: " + id + "type" + type);
+        user.setId(id);
+        Integer res = userService.updateUserById(user);
+
+        if (res == 0) return Result.error("更新用户数据失败");
+
+        log.info("更新用户数据成功");
+        return Result.success("更新用户数据成功");
+    }
+
+//    @DeleteMapping("/user")
+//    public Result deleteUser(@PathVariable String openid) {
+//        log.info("openid: " + openid);
+//        return userService.deleteUser(openid);
+//    }
+
+    @GetMapping("/user")
+    public Result getUserById(@RequestAttribute("id") Integer id) {
+        log.info("获取用户信息,id: " + id);
+
+        User user = userService.getUserById(id);
+
+        if (user == null) return Result.error("用户不存在");
+
+        log.info("用户信息: " + user);
+
+        return Result.success(user);
+    }
+
+    @GetMapping("/user/check_token")
+    public Result checkToken(@RequestHeader("token") String token,@RequestAttribute("id") Integer id,@RequestAttribute("openid") String openid,@RequestAttribute("exp") Integer exp) {
+        log.info("校验token: " + token + "id:" + id + "exp:" + exp);
+
+        HashMap<String, Object> map = new HashMap<String, Object>();
+        map.put("id", id);
+        map.put("openid", openid);
+
+        String newToken = userService.checkToken(map, exp);
+
+        if (newToken == null) return Result.success(token);
+
+        return Result.success(newToken);
+    }
+}

+ 7 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/dao/PyDao.java

@@ -0,0 +1,7 @@
+package cn.flea.chexnetmaster.dao;
+
+import cn.flea.chexnetmaster.pojo.Result;
+
+public interface PyDao {
+    public Result processImg(String InputImage, String OutputImage);
+}

+ 73 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/dao/impl/PyDaoA.java

@@ -0,0 +1,73 @@
+package cn.flea.chexnetmaster.dao.impl;
+
+import cn.flea.chexnetmaster.dao.PyDao;
+import cn.flea.chexnetmaster.pojo.Result;
+import cn.flea.chexnetmaster.util.FilePathUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.stereotype.Repository;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.util.List;
+
+@Slf4j
+@Repository
+public class PyDaoA implements PyDao {
+    @Autowired
+    private ResourceLoader resourceLoader;
+
+    @Autowired
+    private FilePathUtil filePathUtil;
+
+    private String pyPath = "visual.py";
+    private String imgPath = "test\\";
+    private String workingDir = "\\PythonApp\\";
+    @Override
+    public Result processImg(String InputImage, String OutputImage) {
+        String InputWinImage = ".\\test\\" + InputImage;
+        String OutputWinImage = ".\\test\\" + OutputImage;
+
+        try {
+            // 使用 Runtime 类执行 Python 脚本
+            String cmd = "cmd /c cd /d " + filePathUtil.getProjectPath() + this.workingDir + " && python " + pyPath + " " + InputWinImage + " " + OutputWinImage;
+
+            log.info("执行 Python 脚本:" + cmd);
+
+            Process process = Runtime.getRuntime().exec(cmd);
+
+            // 使用 try-with-resources 确保资源被正确关闭
+            try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+                 BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
+
+                // 读取 Python 脚本的标准输出
+                String line;
+                StringBuilder pyOut = new StringBuilder();
+                while ((line = reader.readLine()) != null) {
+                    log.debug(line);
+                    pyOut.append(line + "<br>");
+                }
+                log.info("Python 脚本输出:" + pyOut);
+                // 读取 Python 脚本的错误输出
+                while ((line = errorReader.readLine()) != null) {
+                    System.err.println(line);
+                }
+
+                // 等待子进程结束
+                int exitCode = process.waitFor();
+                if (exitCode != 0) {
+                    return Result.error("Python script failed with exit code: " + exitCode);
+                }
+                return Result.success(List.of(pyOut.toString()));
+//                String OutputImageWinPath = filePathUtil.getFileWinPath(imgPath + OutputImage);
+//                return Result.success(List.of(pyOut.toString(),OutputImage));
+            }
+
+        } catch (IOException | InterruptedException e) {
+            e.printStackTrace();
+            return Result.error("Error occurred: " + e.getMessage());
+        }
+    }
+
+}

+ 13 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/dto/InteractMsg.java

@@ -0,0 +1,13 @@
+package org.lp.medicalai.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class InteractMsg {
+    private MsgDTO userMsg;
+    private MsgDTO assistantMsg;
+}

+ 43 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/dto/MsgDTO.java

@@ -0,0 +1,43 @@
+package org.lp.medicalai.dto;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class MsgDTO {
+    /**
+     * 角色
+     */
+    private String role;
+    /**
+     * 消息内容
+     */
+    private String content;
+    /**
+     * 响应结果字段:结果序号,取值为[0,10]; 当前为保留字段,开发者可忽略
+     */
+    private Integer index;
+
+    public static final String ROLE_USER = "user";
+    public static final String ROLE_System = "system";
+    public static final String ROLE_ASSISTANT = "assistant";
+
+
+    public static MsgDTO createSystemMsg(String tip){
+        return new MsgDTO(ROLE_System,tip,null);
+    }
+
+    public static MsgDTO createUserMsg(String content){
+        return new MsgDTO(ROLE_USER,content,null);
+    }
+
+    public static MsgDTO createAssistantMsg(String content){
+        return new MsgDTO(ROLE_ASSISTANT,content,null);
+    }
+
+}

+ 122 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/dto/RecordsArray.java

@@ -0,0 +1,122 @@
+package org.lp.medicalai.dto;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class RecordsArray {
+
+    /**
+     * 操作锁,默认 false 即未锁
+     * true-已锁
+     * false-未锁
+     */
+    private boolean lock;
+
+    /**
+     * 记录状态,默认为 0
+     * 0: 最新记录
+     * 1: 最近一次交互在 10 分钟前
+     * 2: 最近一次交互在 20 分钟前
+     * ...
+     * 设置最大在 60 分钟后消息被销毁
+     */
+    private int status;
+
+    /**
+     * 表示数组的最大容量,始终留一个空间作为 rear 标记点,实际的允许的交互记录大小为 arraySize-1
+     */
+    private final int arrayMaxSize;
+
+    /**
+     * front 初始值为 0,指向队列的第一个元素, 也就是说 interactMsgArr[front] 就是队列的第一个元素
+     */
+    private int front;
+
+    /**
+     * 队列尾,rear的初始值 = 0,指向队列的最后一个元素的后一个位置,因为希望空出一个空间做为约定
+     */
+    private int rear;
+
+    /**
+     * 存放交互记录,模拟队列
+     */
+    private final InteractMsg[] interactMsgArr;
+
+    public RecordsArray(int maxInteractCount) {
+        // +1 留出一个空间作为 rear 标记点
+        this.arrayMaxSize = maxInteractCount + 1;
+        this.interactMsgArr = new InteractMsg[arrayMaxSize];
+    }
+
+    /**
+     * 判断队列是否满
+     *
+     * @return true-队满,false-未满
+     */
+    public boolean isFull() {
+        return (rear + 1) % arrayMaxSize == front;
+    }
+
+
+    /**
+     * 添加交互消息
+     */
+    public void addInteractMsg(InteractMsg interactMsg) {
+        // 判断队列是否满
+        if (isFull()) {
+            // 队满,front 向后移动相当于将最旧的数据出队列
+            front = (front + 1) % arrayMaxSize;
+        }
+        // 队列未满,无需将最旧的数据出队列,即 front 无需移动
+
+        // 无论是否队满,新的交互信息还是要添加的,因此 rear 处设置为最新的交互消息,并向后移动
+        interactMsgArr[rear] = interactMsg;
+        rear = (rear + 1) % arrayMaxSize;
+    }
+
+    /**
+     * 获取存储的交互消息
+     */
+    public List<MsgDTO> getAllInteractMsg() {
+        int realSize = size();
+        ArrayList<MsgDTO> msgList = new ArrayList<>(realSize * 2);
+        for (int i = front; i < front + realSize; i++) {
+            InteractMsg interactMsg = interactMsgArr[i % arrayMaxSize];
+            if (interactMsg.getUserMsg() != null) {
+                msgList.add(interactMsg.getUserMsg());
+            }
+            if (interactMsg.getAssistantMsg() != null) {
+                msgList.add(interactMsg.getAssistantMsg());
+            }
+        }
+        return msgList;
+    }
+
+    /**
+     * 求出当前队列有效数据的个数
+     *
+     * @return 有效个数
+     */
+    public int size() {
+        //当rear>=front时,有效个数为rear-front
+        //当rear<front时,有效个数为(maxSize-front)+rear
+        return (rear + arrayMaxSize - front) % arrayMaxSize;
+    }
+
+    public int getStatus() {
+        return status;
+    }
+
+    public void setStatus(int status) {
+        this.status = status;
+    }
+
+    public boolean isLock() {
+        return lock;
+    }
+
+    public void setLock(boolean lock) {
+        this.lock = lock;
+    }
+}

+ 81 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/dto/RequestDTO.java

@@ -0,0 +1,81 @@
+package org.lp.medicalai.dto;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@NoArgsConstructor
+@Data
+public class RequestDTO {
+
+    @JsonProperty("header")
+    private HeaderDTO header;
+    @JsonProperty("parameter")
+    private ParameterDTO parameter;
+    @JsonProperty("payload")
+    private PayloadDTO payload;
+
+    @NoArgsConstructor
+    @Data
+    @AllArgsConstructor
+    public static class HeaderDTO {
+        /**
+         * 应用appid,从开放平台控制台创建的应用中获取
+         */
+        @JSONField(name = "app_id")
+        private String appId;
+        /**
+         * 应用appid,从开放平台控制台创建的应用中获取
+         */
+        @JSONField(name = "uid")
+        private String uid;
+    }
+
+    @NoArgsConstructor
+    @Data
+    @AllArgsConstructor
+    public static class ParameterDTO {
+        private ChatDTO chat;
+
+        @NoArgsConstructor
+        @Data
+        @AllArgsConstructor
+        public static class ChatDTO {
+            /**
+             * 指定访问的领域,general指向V1.5版本 generalv2指向V2版本。注意:不同的取值对应的url也不一样!
+             */
+            @JsonProperty("domain")
+            private String domain;
+            /**
+             * 核采样阈值。用于决定结果随机性,取值越高随机性越强即相同的问题得到的不同答案的可能性越高
+             */
+            @JsonProperty("temperature")
+            private Float temperature;
+            /**
+             * 模型回答的tokens的最大长度
+             */
+            @JSONField(name = "max_tokens")
+            private Integer maxTokens;
+        }
+    }
+
+    @NoArgsConstructor
+    @Data
+    @AllArgsConstructor
+    public static class PayloadDTO {
+        @JsonProperty("message")
+        private MessageDTO message;
+
+        @NoArgsConstructor
+        @Data
+        @AllArgsConstructor
+        public static class MessageDTO {
+            @JsonProperty("text")
+            private List<MsgDTO> text;
+        }
+    }
+}

+ 107 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/dto/ResponseDTO.java

@@ -0,0 +1,107 @@
+package org.lp.medicalai.dto;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@NoArgsConstructor
+@Data
+public class ResponseDTO {
+
+    @JsonProperty("header")
+    private HeaderDTO header;
+    @JsonProperty("payload")
+    private PayloadDTO payload;
+
+    @NoArgsConstructor
+    @Data
+    public static class HeaderDTO {
+        /**
+         * 错误码,0表示正常,非0表示出错
+         */
+        @JsonProperty("code")
+        private Integer code;
+        /**
+         * 会话是否成功的描述信息
+         */
+        @JsonProperty("message")
+        private String message;
+        /**
+         * 会话的唯一id,用于讯飞技术人员查询服务端会话日志使用,出现调用错误时建议留存该字段
+         */
+        @JsonProperty("sid")
+        private String sid;
+        /**
+         * 会话状态,取值为[0,1,2];0代表首次结果;1代表中间结果;2代表最后一个结果
+         */
+        @JsonProperty("status")
+        private Integer status;
+    }
+
+    @NoArgsConstructor
+    @Data
+    public static class PayloadDTO {
+        @JsonProperty("choices")
+        private ChoicesDTO choices;
+        /**
+         * 在最后一次结果返回
+         */
+        @JsonProperty("usage")
+        private UsageDTO usage;
+
+        @NoArgsConstructor
+        @Data
+        public static class ChoicesDTO {
+            /**
+             * 文本响应状态,取值为[0,1,2]; 0代表首个文本结果;1代表中间文本结果;2代表最后一个文本结果
+             */
+            @JsonProperty("status")
+            private Integer status;
+            /**
+             * 返回的数据序号,取值为[0,9999999]
+             */
+            @JsonProperty("seq")
+            private Integer seq;
+            /**
+             * 响应文本
+             */
+            @JsonProperty("text")
+            private List<MsgDTO> text;
+
+        }
+
+        @NoArgsConstructor
+        @Data
+        public static class UsageDTO {
+            @JsonProperty("text")
+            private TextDTO text;
+
+            @NoArgsConstructor
+            @Data
+            public static class TextDTO {
+                /**
+                 * 保留字段,可忽略
+                 */
+                @JsonProperty("question_tokens")
+                private Integer questionTokens;
+                /**
+                 * 包含历史问题的总tokens大小
+                 */
+                @JsonProperty("prompt_tokens")
+                private Integer promptTokens;
+                /**
+                 * 回答的tokens大小
+                 */
+                @JsonProperty("completion_tokens")
+                private Integer completionTokens;
+                /**
+                 * prompt_tokens和completion_tokens的和,也是本次交互计费的tokens大小
+                 */
+                @JsonProperty("total_tokens")
+                private Integer totalTokens;
+            }
+        }
+    }
+}

+ 57 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/listener/XfXhWebSocketListener.java

@@ -0,0 +1,57 @@
+package org.lp.medicalai.listener;
+
+import com.alibaba.fastjson.JSONObject;
+import org.lp.medicalai.dto.MsgDTO;
+import org.lp.medicalai.dto.ResponseDTO;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.Response;
+import okhttp3.WebSocket;
+import okhttp3.WebSocketListener;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.lang.Nullable;
+
+@Data
+@Slf4j
+public class XfXhWebSocketListener extends WebSocketListener {
+    private StringBuilder answer = new StringBuilder();
+
+    private boolean wsCloseFlag = false;
+
+    @Override
+    public void onOpen(@NotNull WebSocket webSocket, @NotNull Response response) {
+        super.onOpen(webSocket, response);
+    }
+
+    @Override
+    public void onMessage(@NotNull WebSocket webSocket, @NotNull String text) {
+        super.onMessage(webSocket, text);
+        ResponseDTO responseData = JSONObject.parseObject(text, ResponseDTO.class);
+        if (responseData.getHeader().getCode() != 0) {
+            // 日志记录
+            log.error("发生错误,错误码为:" + responseData.getHeader().getCode() + "; " + "信息:" + responseData.getHeader().getMessage());
+            // 记录信息
+            this.answer = new StringBuilder("大模型响应错误,请稍后再试");
+            wsCloseFlag = true;
+            return;
+        }
+        // 将回答进行拼接
+        for (MsgDTO msgDTO : responseData.getPayload().getChoices().getText()) {
+            this.answer.append(msgDTO.getContent());
+        }
+        // 对最后一个文本结果进行处理
+        if (2 == responseData.getHeader().getStatus()) {
+            wsCloseFlag = true;
+        }
+    }
+
+    @Override
+    public void onFailure(@NotNull WebSocket webSocket, @NotNull Throwable t, @Nullable Response response) {
+        super.onFailure(webSocket, t, response);
+    }
+
+    @Override
+    public void onClosed(@NotNull WebSocket webSocket, int code, @NotNull String reason) {
+        super.onClosed(webSocket, code, reason);
+    }
+}

+ 35 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/mapper/UserMapper.java

@@ -0,0 +1,35 @@
+package cn.flea.chexnetmaster.mapper;
+
+import cn.flea.chexnetmaster.pojo.User;
+import org.apache.ibatis.annotations.*;
+
+import java.util.List;
+
+@Mapper
+public interface UserMapper {
+
+//    @Select("SELECT * FROM user WHERE id = #{id}")
+//    User getUserById(Integer id);
+
+//    @Select("SELECT * FROM user")
+//    List<User> getAllUsers();
+
+//    @Select("SELECT * FROM user WHERE name = #{name} and password = #{name}")
+//    User getUserByNameAndPassword(String name, String password);
+
+//    @Delete("DELETE FROM user WHERE id = #{id}")
+//    int deleteUserById(Integer id);
+
+    int addUser(User user);
+
+    int deleteUserByOpenid(String wechatOpenid);
+
+    int updateUserById(User user);
+
+    int updateUserByOpenid(User user);
+
+    User getUserByOpenid(String wechatOpenid);
+
+    User getUserById(Integer id);
+
+}

+ 30 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/pojo/Result.java

@@ -0,0 +1,30 @@
+package cn.flea.chexnetmaster.pojo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+
+public class Result {
+    private Integer code;//1 成功 , 0 失败
+    private String msg;  //提示信息
+    private Object data; //数据 data
+
+    public static Result success(String msg, Object data) {
+        return new Result(1, msg, data);
+    }
+    public static Result success(Object data) {
+        return new Result(1, "success", data);
+    }
+
+    public static Result success() {
+        return new Result(1, "success", null);
+    }
+
+    public static Result error(String msg) {
+        return new Result(0, msg, null);
+    }
+}

+ 24 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/pojo/User.java

@@ -0,0 +1,24 @@
+package cn.flea.chexnetmaster.pojo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class User {
+    private Integer id;
+    private String name;
+    private String password;
+    private Integer gender;
+    private Integer age;
+    private String wechatOpenid;
+    private String wechatUnionid;
+    private String sessionKey;
+    private String wechatAvatarUrl;
+    private Date createTime;
+    private Date updateTime;
+}

+ 9 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/service/ContentCheckService.java

@@ -0,0 +1,9 @@
+package cn.flea.chexnetmaster.service;
+
+import org.springframework.web.multipart.MultipartFile;
+
+public interface ContentCheckService {
+    Integer textCheck(String text, String openid);
+
+    Integer imgCheck(MultipartFile img, String openid);
+}

+ 8 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/service/ProcessImgService.java

@@ -0,0 +1,8 @@
+package cn.flea.chexnetmaster.service;
+
+import cn.flea.chexnetmaster.pojo.Result;
+import org.springframework.web.multipart.MultipartFile;
+
+public interface ProcessImgService {
+    public Result processImg(MultipartFile img, String chexnetMasterImgApiUrl);
+}

+ 7 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/service/PyService.java

@@ -0,0 +1,7 @@
+package cn.flea.chexnetmaster.service;
+
+import cn.flea.chexnetmaster.pojo.Result;
+
+public interface PyService {
+    public Result processImg(String InputImage);
+}

+ 17 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/service/UserService.java

@@ -0,0 +1,17 @@
+package cn.flea.chexnetmaster.service;
+
+import cn.flea.chexnetmaster.pojo.Result;
+import cn.flea.chexnetmaster.pojo.User;
+
+import java.util.HashMap;
+
+public interface UserService {
+    public Result login(String code);
+    public int addUser(User user);
+    public int deleteUser(String wechatOpenid);
+    public int updateUserById(User user);
+    public int updateUserByOpenid(User user);
+    public User getUserById(Integer id);
+    public User getUserByOpenid(String wechatOpenid);
+    public String checkToken(HashMap<String, Object> map, Integer exp);
+}

+ 67 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/service/impl/ContentCheckServiceA.java

@@ -0,0 +1,67 @@
+package cn.flea.chexnetmaster.service.impl;
+
+import cn.flea.chexnetmaster.service.ContentCheckService;
+import cn.flea.chexnetmaster.util.WeiXinUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.Map;
+
+@Slf4j
+@Service
+public class ContentCheckServiceA implements ContentCheckService {
+    @Autowired
+    private WeiXinUtil weiXinUtil;
+
+    /**
+     * 文本检测, 返回0为检测失败,1为文本正常,2为文本违规
+     *
+     * @param text
+     * @param openid
+     * @return
+     */
+    @Override
+    public Integer textCheck(String text, String openid) {
+        Map<String, Object> map = weiXinUtil.textCheck(text, openid);
+        log.info(text + "文本检测结果: " + map);
+
+        try {
+            Integer res = ((Double) map.get("errcode")).intValue();
+            if (res == 0) {
+                map = (Map<String, Object>) map.get("result");
+                if (map.get("suggest").equals("pass")) return 1;
+                return 2;
+            }
+        } catch (Exception e) {
+
+        }
+
+        return 0;
+    }
+
+    /**
+     * 图片检测, 返回0为检测失败,1为图片正常,2为图片违规
+     *
+     * @param img
+     * @param openid
+     * @return
+     */
+
+    @Override
+    public Integer imgCheck(MultipartFile img, String openid) {
+        Map<String, Object> map = weiXinUtil.imgCheck(img);
+        log.info("图片检测结果: " + map);
+
+        try {
+            Integer res = ((Double) map.get("errcode")).intValue();
+            if (res == 0) return 1;
+            if (res == 87014) return 2;
+        } catch (Exception e) {
+
+        }
+
+        return 0;
+    }
+}

+ 50 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/service/impl/ProcessImgServiceB.java

@@ -0,0 +1,50 @@
+package cn.flea.chexnetmaster.service.impl;
+
+import cn.flea.chexnetmaster.pojo.Result;
+import cn.flea.chexnetmaster.service.ProcessImgService;
+import cn.flea.chexnetmaster.util.FileUploadUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.Map;
+
+@Slf4j
+@Service
+public class ProcessImgServiceB implements ProcessImgService {
+
+//    @Autowired
+//    private GetChexnetMasterImgApiUrl getChexnetMasterImgApiUrl;
+//
+//    @PostConstruct
+//    public void init() {
+//        chexnetMasterImgApiUrl = getChexnetMasterImgApiUrl.getChexnetMasterImgApiUrl();
+//    }
+
+    @Override
+    public Result processImg(MultipartFile img, String chexnetMasterImgApiUrl) {
+        try {
+            Map<String, Object> res = FileUploadUtil.uploadFileMap(chexnetMasterImgApiUrl, img, "img");
+            log.info("图片处理结果:" + res.get("code") + res.get("msg"));
+            Result result = new Result();
+            // 检查并转换 code 值
+            Object codeObj = res.get("code");
+            if (codeObj instanceof Integer) {
+                result.setCode((Integer) codeObj);
+            } else if (codeObj instanceof Double) {
+                result.setCode(((Double) codeObj).intValue());
+            } else {
+                throw new IllegalArgumentException("Unexpected type for code: " + codeObj.getClass().getName());
+            }
+            result.setMsg((String) res.get("msg"));
+            result.setData(res.get("data"));
+
+            log.info("处理图片完成");
+            return result;
+
+        } catch (Exception e){
+            log.error("图片处理失败");
+            return Result.error("图片处理失败");
+        }
+    }
+}

+ 28 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/service/impl/PyServiceA.java

@@ -0,0 +1,28 @@
+package cn.flea.chexnetmaster.service.impl;
+
+import cn.flea.chexnetmaster.dao.PyDao;
+import cn.flea.chexnetmaster.pojo.Result;
+import cn.flea.chexnetmaster.service.PyService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class PyServiceA implements PyService {
+    @Autowired
+    private PyDao pyDao;
+    @Override
+    public Result processImg(String InputImage) {
+        String OutputImage = this.modifyFileName(InputImage);
+        return pyDao.processImg(InputImage, OutputImage);
+    }
+
+    public static String modifyFileName(String fileName) {
+        int dotIndex = fileName.lastIndexOf(".");
+        if (dotIndex == -1) {
+            return fileName + "_out"; // 如果没有扩展名,直接添加_out
+        }
+        String namePart = fileName.substring(0, dotIndex);
+        String extensionPart = fileName.substring(dotIndex);
+        return namePart + "_out" + extensionPart;
+    }
+}

+ 123 - 0
chexnet-master-service/src/main/java/cn/flea/chexnetmaster/service/impl/UserServiceA.java

@@ -0,0 +1,123 @@
+package cn.flea.chexnetmaster.service.impl;
+
+import cn.flea.chexnetmaster.mapper.UserMapper;
+import cn.flea.chexnetmaster.pojo.Result;
+import cn.flea.chexnetmaster.pojo.User;
+import cn.flea.chexnetmaster.service.UserService;
+import cn.flea.chexnetmaster.util.JwtUtil;
+import cn.flea.chexnetmaster.util.WeiXinUtil;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+
+@Slf4j
+@Service
+public class UserServiceA implements UserService {
+    @Autowired
+    WeiXinUtil weiXinUtil;
+
+    @Autowired
+    UserMapper userMapper;
+
+    @Override
+    public Result login(String code) {
+        String res = weiXinUtil.getOpenid(code);
+        log.info(res);
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            // 将String解析为JsonNode
+            JsonNode jsonNode = objectMapper.readTree(res);
+
+            String openid = jsonNode.get("openid").asText();
+            String sessionKey = jsonNode.get("session_key").asText();
+            String unionid = jsonNode.get("unionid").asText();
+
+            User user = userMapper.getUserByOpenid(openid);
+
+            if (user == null) {
+                log.info("用户不存在,创建新用户");
+
+                user = new User();
+                user.setName("微信用户");
+                user.setSessionKey(sessionKey);
+                user.setWechatOpenid(openid);
+                user.setWechatUnionid(unionid);
+                Integer id = addUser(user);
+
+                HashMap<String, Object> map = new HashMap<String, Object>();
+                map.put("id", id);
+                map.put("openid", openid);
+
+                HashMap<String, String> info = new HashMap<String, String>();
+                info.put("name", user.getName());
+                info.put("token",JwtUtil.getJwt(map));
+
+                return Result.success("new", info);
+            } else {
+                log.info("用户已存在,更新用户session_key");
+                user.setSessionKey(sessionKey);
+                Integer id = updateUserByOpenid(user);
+
+                HashMap<String, Object> map = new HashMap<String, Object>();
+                map.put("id", id);
+                map.put("openid", openid);
+
+                HashMap<String, String> info = new HashMap<String, String>();
+                info.put("name", user.getName());
+                info.put("token",JwtUtil.getJwt(map));
+
+                return Result.success("old", info);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return Result.error("登录失败");
+    }
+
+    public int addUser(User user) {
+        userMapper.addUser(user);
+        int id = user.getId();
+        log.info("用户添加成功:" + id);
+        return id;
+    }
+
+    @Override
+    public int deleteUser(String wechatOpenid) {
+        return userMapper.deleteUserByOpenid(wechatOpenid);
+    }
+
+    @Override
+    public int updateUserByOpenid(User user) {
+        userMapper.updateUserByOpenid(user);
+        int id = user.getId();
+        log.info("用户更新成功:" + id);
+        return id;
+    }
+
+    @Override
+    public int updateUserById(User user) {
+        return userMapper.updateUserById(user);
+    }
+
+    @Override
+    public User getUserByOpenid(String wechatOpenid) {
+        return userMapper.getUserByOpenid(wechatOpenid);
+    }
+
+    @Override
+    public String checkToken(HashMap<String, Object> map, Integer exp) {
+
+        if (exp < 24 * 60 * 60 * 1000) return JwtUtil.getJwt(map);
+
+        return null;
+    }
+
+    @Override
+    public User getUserById(Integer id) {
+        return userMapper.getUserById(id);
+    }
+}

+ 0 - 0
chexnet-master-service/src/main/resources/application.yml


+ 87 - 0
chexnet-master-service/src/main/resources/cn/flea/chexnetmaster/mapper/UserMapper.xml

@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.flea.chexnetmaster.mapper.UserMapper">
+    <insert id="addUser" useGeneratedKeys="true" keyProperty="id">
+        insert into
+        user(name,password,gender,age,wechat_openid,wechat_unionid,session_key,wechat_avatar_url,create_time,update_time)
+        values(#{name},#{password},#{gender},#{age},#{wechatOpenid},#{wechatUnionid},#{sessionKey},#{wechatAvatarUrl},now(),now())
+    </insert>
+
+    <delete id="deleteUserByOpenid">
+        delete from user where wechat_openid=#{wechatOpenid}
+    </delete>
+
+    <update id="updateUserById" useGeneratedKeys="true" keyProperty="id">
+        update user
+        <set>
+            <if test="name != null and name != ''" >
+                name=#{name},
+            </if>
+            <if test="password != null and password != ''" >
+                password=#{password},
+            </if>
+            <if test="gender != null" >
+                gender=#{gender},
+            </if>
+            <if test="age != null" >
+                age=#{age},
+            </if>
+            <if test="wechatOpenid != null and wechatOpenid != ''" >
+                wechat_openid=#{wechatOpenid},
+            </if>
+            <if test="wechatUnionid != null and wechatUnionid != ''" >
+                wechat_unionid=#{wechatUnionid},
+            </if>
+            <if test="sessionKey != null and sessionKey != ''" >
+                session_key=#{sessionKey},
+            </if>
+            <if test="wechatAvatarUrl != null and wechatAvatarUrl != ''" >
+                wechat_avatar_url=#{wechatAvatarUrl},
+            </if>
+            update_time=now()
+        </set>
+        where id=#{id}
+    </update>
+
+    <update id="updateUserByOpenid" useGeneratedKeys="true" keyProperty="id">
+        update user
+        <set>
+            <if test="name != null and name != ''" >
+                name=#{name},
+            </if>
+            <if test="password != null and password != ''" >
+                password=#{password},
+            </if>
+            <if test="gender != null" >
+                gender=#{gender},
+            </if>
+            <if test="age != null" >
+                age=#{age},
+            </if>
+            <if test="wechatOpenid != null and wechatOpenid != ''" >
+                wechat_openid=#{wechatOpenid},
+            </if>
+            <if test="wechatUnionid != null and wechatUnionid != ''" >
+                    wechat_unionid=#{wechatUnionid},
+            </if>
+            <if test="sessionKey != null and sessionKey != ''" >
+                session_key=#{sessionKey},
+            </if>
+            <if test="wechatAvatarUrl != null and wechatAvatarUrl != ''" >
+                wechat_avatar_url=#{wechatAvatarUrl},
+            </if>
+            update_time=now()
+        </set>
+        where wechat_openid=#{wechatOpenid}
+    </update>
+
+    <select id="getUserByOpenid" resultType="cn.flea.chexnetmaster.pojo.User">
+        select * from user where wechat_openid=#{wechatOpenid}
+    </select>
+
+    <select id="getUserById" resultType="cn.flea.chexnetmaster.pojo.User">
+        select name,gender,age from user where id=#{id}
+    </select>
+</mapper>

Некоторые файлы не были показаны из-за большого количества измененных файлов