jwyu 2 жил өмнө
commit
a412df3115

+ 6 - 0
.env.development

@@ -0,0 +1,6 @@
+# 接口地址
+VITE_APP_API_URL="http://8.136.199.33:8612/api"
+# 路由根地址
+VITE_APP_BASE_URL="/"
+# 打包输入文件名
+VITE_APP_OUTDIR="dist"

+ 6 - 0
.env.production

@@ -0,0 +1,6 @@
+# 接口地址
+VITE_APP_API_URL="https://yanbao.hzinsights.com/api"
+# 路由根地址
+VITE_APP_BASE_URL="/"
+# 打包输入文件名
+VITE_APP_OUTDIR="hongze_yb_en"

+ 6 - 0
.env.test

@@ -0,0 +1,6 @@
+# 接口地址
+VITE_APP_API_URL="https://ybpctest.hzinsights.com/api"
+# 路由根地址
+VITE_APP_BASE_URL="/"
+# 打包输入文件名
+VITE_APP_OUTDIR="hongze_yb_en"

+ 27 - 0
.gitignore

@@ -0,0 +1,27 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+package-lock.json
+hongze_yb_en
+hongze_yb_en.zip
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 3 - 0
.vscode/extensions.json

@@ -0,0 +1,3 @@
+{
+  "recommendations": ["Vue.volar"]
+}

+ 7 - 0
README.md

@@ -0,0 +1,7 @@
+# Vue 3 + Vite
+
+This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
+
+## Recommended IDE Setup
+
+- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar)

+ 13 - 0
index.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <link rel="icon" href="/favicon.ico" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>HORIZON INSIGHTS</title>
+  </head>
+  <body>
+    <div id="app"></div>
+    <script type="module" src="/src/main.js"></script>
+  </body>
+</html>

+ 24 - 0
package.json

@@ -0,0 +1,24 @@
+{
+  "name": "hongze_yb_en",
+  "private": true,
+  "version": "0.0.0",
+  "type": "module",
+  "scripts": {
+    "dev": "vite --host 0.0.0.0",
+    "build": "vite build --mode production",
+    "build.test": "vite build --mode test",
+    "preview": "vite preview"
+  },
+  "dependencies": {
+    "axios": "^1.2.0",
+    "element-plus": "^2.2.25",
+    "normalize.css": "^8.0.1",
+    "vue": "^3.2.41",
+    "vue-router": "^4.1.6"
+  },
+  "devDependencies": {
+    "@vitejs/plugin-vue": "^3.2.0",
+    "sass": "^1.56.1",
+    "vite": "^3.2.3"
+  }
+}

BIN
public/favicon.ico


+ 17 - 0
src/App.vue

@@ -0,0 +1,17 @@
+<script setup>
+</script>
+
+<template>
+  <div class="main-wrap">
+    <router-view />
+    <el-backtop :right="100" :bottom="100" />
+  </div>
+  
+</template>
+
+<style scoped>
+.main-wrap{
+  max-width: 1200px;
+  margin: 0 auto;
+}
+</style>

+ 787 - 0
src/api/crypto.js

@@ -0,0 +1,787 @@
+const key = 'zDeESsxsXuionhqSLZYHWcDJ';
+
+class CryptoJS {
+	// 3DES加密,CBC/PKCS5Padding
+	static Des3Encrypt (input) {
+		let genKey = genkey(key, 0, 24);
+		return base64encode(des(genKey.key, input, 1, 1, key.substr(0, 8), 1));
+	}
+
+	// 3DES解密,CBC/PKCS5Padding
+	static Des3Decrypt (input) {
+		let genKey = genkey(key, 0, 24);
+		return des(genKey.key, base64decode(input), 0, 1, key.substr(0, 8), 1);
+	}
+
+	// md5
+	static Md5Encrypt (input) {
+		return md5(String(input));
+	}
+}
+
+function des (key, message, encrypt, mode, iv, padding) {
+	if (encrypt) // 如果是加密的话,首先转换编码
+	{ message = unescape(encodeURIComponent(message)); }
+	// declaring this locally speeds things up a bit
+	let spfunction1 = new Array(0x1010400, 0, 0x10000, 0x1010404, 0x1010004, 0x10404, 0x4, 0x10000, 0x400, 0x1010400, 0x1010404, 0x400, 0x1000404, 0x1010004, 0x1000000, 0x4, 0x404, 0x1000400, 0x1000400, 0x10400, 0x10400, 0x1010000, 0x1010000, 0x1000404, 0x10004, 0x1000004, 0x1000004, 0x10004, 0, 0x404, 0x10404, 0x1000000, 0x10000, 0x1010404, 0x4, 0x1010000, 0x1010400, 0x1000000, 0x1000000, 0x400, 0x1010004, 0x10000, 0x10400, 0x1000004, 0x400, 0x4, 0x1000404, 0x10404, 0x1010404, 0x10004, 0x1010000, 0x1000404, 0x1000004, 0x404, 0x10404, 0x1010400, 0x404, 0x1000400, 0x1000400, 0, 0x10004, 0x10400, 0, 0x1010004);
+	let spfunction2 = new Array(-0x7fef7fe0, -0x7fff8000, 0x8000, 0x108020, 0x100000, 0x20, -0x7fefffe0, -0x7fff7fe0, -0x7fffffe0, -0x7fef7fe0, -0x7fef8000, -0x80000000, -0x7fff8000, 0x100000, 0x20, -0x7fefffe0, 0x108000, 0x100020, -0x7fff7fe0, 0, -0x80000000, 0x8000, 0x108020, -0x7ff00000, 0x100020, -0x7fffffe0, 0, 0x108000, 0x8020, -0x7fef8000, -0x7ff00000, 0x8020, 0, 0x108020, -0x7fefffe0, 0x100000, -0x7fff7fe0, -0x7ff00000, -0x7fef8000, 0x8000, -0x7ff00000, -0x7fff8000, 0x20, -0x7fef7fe0, 0x108020, 0x20, 0x8000, -0x80000000, 0x8020, -0x7fef8000, 0x100000, -0x7fffffe0, 0x100020, -0x7fff7fe0, -0x7fffffe0, 0x100020, 0x108000, 0, -0x7fff8000, 0x8020, -0x80000000, -0x7fefffe0, -0x7fef7fe0, 0x108000);
+	let spfunction3 = new Array(0x208, 0x8020200, 0, 0x8020008, 0x8000200, 0, 0x20208, 0x8000200, 0x20008, 0x8000008, 0x8000008, 0x20000, 0x8020208, 0x20008, 0x8020000, 0x208, 0x8000000, 0x8, 0x8020200, 0x200, 0x20200, 0x8020000, 0x8020008, 0x20208, 0x8000208, 0x20200, 0x20000, 0x8000208, 0x8, 0x8020208, 0x200, 0x8000000, 0x8020200, 0x8000000, 0x20008, 0x208, 0x20000, 0x8020200, 0x8000200, 0, 0x200, 0x20008, 0x8020208, 0x8000200, 0x8000008, 0x200, 0, 0x8020008, 0x8000208, 0x20000, 0x8000000, 0x8020208, 0x8, 0x20208, 0x20200, 0x8000008, 0x8020000, 0x8000208, 0x208, 0x8020000, 0x20208, 0x8, 0x8020008, 0x20200);
+	let spfunction4 = new Array(0x802001, 0x2081, 0x2081, 0x80, 0x802080, 0x800081, 0x800001, 0x2001, 0, 0x802000, 0x802000, 0x802081, 0x81, 0, 0x800080, 0x800001, 0x1, 0x2000, 0x800000, 0x802001, 0x80, 0x800000, 0x2001, 0x2080, 0x800081, 0x1, 0x2080, 0x800080, 0x2000, 0x802080, 0x802081, 0x81, 0x800080, 0x800001, 0x802000, 0x802081, 0x81, 0, 0, 0x802000, 0x2080, 0x800080, 0x800081, 0x1, 0x802001, 0x2081, 0x2081, 0x80, 0x802081, 0x81, 0x1, 0x2000, 0x800001, 0x2001, 0x802080, 0x800081, 0x2001, 0x2080, 0x800000, 0x802001, 0x80, 0x800000, 0x2000, 0x802080);
+	let spfunction5 = new Array(0x100, 0x2080100, 0x2080000, 0x42000100, 0x80000, 0x100, 0x40000000, 0x2080000, 0x40080100, 0x80000, 0x2000100, 0x40080100, 0x42000100, 0x42080000, 0x80100, 0x40000000, 0x2000000, 0x40080000, 0x40080000, 0, 0x40000100, 0x42080100, 0x42080100, 0x2000100, 0x42080000, 0x40000100, 0, 0x42000000, 0x2080100, 0x2000000, 0x42000000, 0x80100, 0x80000, 0x42000100, 0x100, 0x2000000, 0x40000000, 0x2080000, 0x42000100, 0x40080100, 0x2000100, 0x40000000, 0x42080000, 0x2080100, 0x40080100, 0x100, 0x2000000, 0x42080000, 0x42080100, 0x80100, 0x42000000, 0x42080100, 0x2080000, 0, 0x40080000, 0x42000000, 0x80100, 0x2000100, 0x40000100, 0x80000, 0, 0x40080000, 0x2080100, 0x40000100);
+	let spfunction6 = new Array(0x20000010, 0x20400000, 0x4000, 0x20404010, 0x20400000, 0x10, 0x20404010, 0x400000, 0x20004000, 0x404010, 0x400000, 0x20000010, 0x400010, 0x20004000, 0x20000000, 0x4010, 0, 0x400010, 0x20004010, 0x4000, 0x404000, 0x20004010, 0x10, 0x20400010, 0x20400010, 0, 0x404010, 0x20404000, 0x4010, 0x404000, 0x20404000, 0x20000000, 0x20004000, 0x10, 0x20400010, 0x404000, 0x20404010, 0x400000, 0x4010, 0x20000010, 0x400000, 0x20004000, 0x20000000, 0x4010, 0x20000010, 0x20404010, 0x404000, 0x20400000, 0x404010, 0x20404000, 0, 0x20400010, 0x10, 0x4000, 0x20400000, 0x404010, 0x4000, 0x400010, 0x20004010, 0, 0x20404000, 0x20000000, 0x400010, 0x20004010);
+	let spfunction7 = new Array(0x200000, 0x4200002, 0x4000802, 0, 0x800, 0x4000802, 0x200802, 0x4200800, 0x4200802, 0x200000, 0, 0x4000002, 0x2, 0x4000000, 0x4200002, 0x802, 0x4000800, 0x200802, 0x200002, 0x4000800, 0x4000002, 0x4200000, 0x4200800, 0x200002, 0x4200000, 0x800, 0x802, 0x4200802, 0x200800, 0x2, 0x4000000, 0x200800, 0x4000000, 0x200800, 0x200000, 0x4000802, 0x4000802, 0x4200002, 0x4200002, 0x2, 0x200002, 0x4000000, 0x4000800, 0x200000, 0x4200800, 0x802, 0x200802, 0x4200800, 0x802, 0x4000002, 0x4200802, 0x4200000, 0x200800, 0, 0x2, 0x4200802, 0, 0x200802, 0x4200000, 0x800, 0x4000002, 0x4000800, 0x800, 0x200002);
+	let spfunction8 = new Array(0x10001040, 0x1000, 0x40000, 0x10041040, 0x10000000, 0x10001040, 0x40, 0x10000000, 0x40040, 0x10040000, 0x10041040, 0x41000, 0x10041000, 0x41040, 0x1000, 0x40, 0x10040000, 0x10000040, 0x10001000, 0x1040, 0x41000, 0x40040, 0x10040040, 0x10041000, 0x1040, 0, 0, 0x10040040, 0x10000040, 0x10001000, 0x41040, 0x40000, 0x41040, 0x40000, 0x10041000, 0x1000, 0x40, 0x10040040, 0x1000, 0x41040, 0x10001000, 0x40, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x40000, 0x10001040, 0, 0x10041040, 0x40040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0, 0x10041040, 0x41000, 0x41000, 0x1040, 0x1040, 0x40040, 0x10000000, 0x10041000);
+
+	// create the 16 or 48 subkeys we will need
+	let keys = des_createKeys(key);
+
+	let m = 0, i, j, temp, temp2, right1, right2, left, right, looping;
+	let cbcleft, cbcleft2, cbcright, cbcright2;
+	let endloop, loopinc;
+	var len = message.length;
+	let chunk = 0;
+	// set up the loops for single and triple des
+	let iterations = keys.length === 32 ? 3 : 9; // single or triple des
+	if (iterations === 3) { looping = encrypt ? new Array(0, 32, 2) : new Array(30, -2, -2); } else { looping = encrypt ? new Array(0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array(94, 62, -2, 32, 64, 2, 30, -2, -2); }
+
+	// pad the message depending on the padding parameter
+	if (padding === 2) message += '        '; // pad the message with spaces
+	else if (padding === 1) {
+		if (encrypt) {
+			temp = 8 - (len % 8);
+			message += String.fromCharCode(temp, temp, temp, temp, temp, temp, temp, temp);
+			if (temp === 8) len += 8;
+		}
+	} // PKCS7 padding
+	else if (!padding) message += '\0\0\0\0\0\0\0\0'; // pad the message out with null bytes
+
+	// store the result here
+	let result = '';
+	let tempresult = '';
+
+	if (mode === 1) { // CBC mode
+		cbcleft = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
+		cbcright = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
+		m = 0;
+	}
+
+	// loop through each 64 bit chunk of the message
+	while (m < len) {
+		left = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++);
+		right = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++);
+
+		// for Cipher Block Chaining mode, xor the message with the previous result
+		if (mode === 1) {
+			if (encrypt) {
+				left ^= cbcleft;
+				right ^= cbcright;
+			} else {
+				cbcleft2 = cbcleft;
+				cbcright2 = cbcright;
+				cbcleft = left;
+				cbcright = right;
+			}
+		}
+
+		// first each 64 but chunk of the message must be permuted according to IP
+		temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
+		right ^= temp;
+		left ^= (temp << 4);
+		temp = ((left >>> 16) ^ right) & 0x0000ffff;
+		right ^= temp;
+		left ^= (temp << 16);
+		temp = ((right >>> 2) ^ left) & 0x33333333;
+		left ^= temp;
+		right ^= (temp << 2);
+		temp = ((right >>> 8) ^ left) & 0x00ff00ff;
+		left ^= temp;
+		right ^= (temp << 8);
+		temp = ((left >>> 1) ^ right) & 0x55555555;
+		right ^= temp;
+		left ^= (temp << 1);
+
+		left = ((left << 1) | (left >>> 31));
+		right = ((right << 1) | (right >>> 31));
+
+		// do this either 1 or 3 times for each chunk of the message
+		for (j = 0; j < iterations; j += 3) {
+			endloop = looping[j + 1];
+			loopinc = looping[j + 2];
+			// now go through and perform the encryption or decryption
+			for (i = looping[j]; i !== endloop; i += loopinc) { // for efficiency
+				right1 = right ^ keys[i];
+				right2 = ((right >>> 4) | (right << 28)) ^ keys[i + 1];
+				// the result is attained by passing these bytes through the S selection functions
+				temp = left;
+				left = right;
+				right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f] |
+					spfunction6[(right1 >>> 8) & 0x3f] | spfunction8[right1 & 0x3f] |
+					spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & 0x3f] |
+					spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]);
+			}
+			temp = left;
+			left = right;
+			right = temp; // unreverse left and right
+		} // for either 1 or 3 iterations
+
+		// move then each one bit to the right
+		left = ((left >>> 1) | (left << 31));
+		right = ((right >>> 1) | (right << 31));
+
+		// now perform IP-1, which is IP in the opposite direction
+		temp = ((left >>> 1) ^ right) & 0x55555555;
+		right ^= temp;
+		left ^= (temp << 1);
+		temp = ((right >>> 8) ^ left) & 0x00ff00ff;
+		left ^= temp;
+		right ^= (temp << 8);
+		temp = ((right >>> 2) ^ left) & 0x33333333;
+		left ^= temp;
+		right ^= (temp << 2);
+		temp = ((left >>> 16) ^ right) & 0x0000ffff;
+		right ^= temp;
+		left ^= (temp << 16);
+		temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
+		right ^= temp;
+		left ^= (temp << 4);
+
+		// for Cipher Block Chaining mode, xor the message with the previous result
+		if (mode === 1) {
+			if (encrypt) {
+				cbcleft = left;
+				cbcright = right;
+			} else {
+				left ^= cbcleft2;
+				right ^= cbcright2;
+			}
+		}
+		tempresult += String.fromCharCode((left >>> 24), ((left >>> 16) & 0xff), ((left >>> 8) & 0xff), (left & 0xff), (right >>> 24), ((right >>> 16) & 0xff), ((right >>> 8) & 0xff), (right & 0xff));
+
+		chunk += 8;
+		if (chunk === 512) {
+			result += tempresult;
+			tempresult = '';
+			chunk = 0;
+		}
+	} // for every 8 characters, or 64 bits in the message
+
+	// return the result as an array
+	result += tempresult;
+	result = result.replace(/\0*$/g, '');
+
+	if (!encrypt) { // 如果是解密的话,解密结束后对PKCS7 padding进行解码,并转换成utf-8编码
+		if (padding === 1) { // PKCS7 padding解码
+			var len = result.length, paddingChars = 0;
+			len && (paddingChars = result.charCodeAt(len - 1));
+			(paddingChars <= 8) && (result = result.substring(0, len - paddingChars));
+		}
+		// 转换成UTF-8编码
+		result = decodeURIComponent(escape(result));
+	}
+
+	return result;
+} // end of des
+
+// des_createKeys
+// this takes as input a 64 bit key (even though only 56 bits are used)
+// as an array of 2 integers, and returns 16 48 bit keys
+function des_createKeys (key) {
+	// declaring this locally speeds things up a bit
+	let pc2bytes0 = new Array(0, 0x4, 0x20000000, 0x20000004, 0x10000, 0x10004, 0x20010000, 0x20010004, 0x200, 0x204, 0x20000200, 0x20000204, 0x10200, 0x10204, 0x20010200, 0x20010204);
+	let pc2bytes1 = new Array(0, 0x1, 0x100000, 0x100001, 0x4000000, 0x4000001, 0x4100000, 0x4100001, 0x100, 0x101, 0x100100, 0x100101, 0x4000100, 0x4000101, 0x4100100, 0x4100101);
+	let pc2bytes2 = new Array(0, 0x8, 0x800, 0x808, 0x1000000, 0x1000008, 0x1000800, 0x1000808, 0, 0x8, 0x800, 0x808, 0x1000000, 0x1000008, 0x1000800, 0x1000808);
+	let pc2bytes3 = new Array(0, 0x200000, 0x8000000, 0x8200000, 0x2000, 0x202000, 0x8002000, 0x8202000, 0x20000, 0x220000, 0x8020000, 0x8220000, 0x22000, 0x222000, 0x8022000, 0x8222000);
+	let pc2bytes4 = new Array(0, 0x40000, 0x10, 0x40010, 0, 0x40000, 0x10, 0x40010, 0x1000, 0x41000, 0x1010, 0x41010, 0x1000, 0x41000, 0x1010, 0x41010);
+	let pc2bytes5 = new Array(0, 0x400, 0x20, 0x420, 0, 0x400, 0x20, 0x420, 0x2000000, 0x2000400, 0x2000020, 0x2000420, 0x2000000, 0x2000400, 0x2000020, 0x2000420);
+	let pc2bytes6 = new Array(0, 0x10000000, 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002, 0, 0x10000000, 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002);
+	let pc2bytes7 = new Array(0, 0x10000, 0x800, 0x10800, 0x20000000, 0x20010000, 0x20000800, 0x20010800, 0x20000, 0x30000, 0x20800, 0x30800, 0x20020000, 0x20030000, 0x20020800, 0x20030800);
+	let pc2bytes8 = new Array(0, 0x40000, 0, 0x40000, 0x2, 0x40002, 0x2, 0x40002, 0x2000000, 0x2040000, 0x2000000, 0x2040000, 0x2000002, 0x2040002, 0x2000002, 0x2040002);
+	let pc2bytes9 = new Array(0, 0x10000000, 0x8, 0x10000008, 0, 0x10000000, 0x8, 0x10000008, 0x400, 0x10000400, 0x408, 0x10000408, 0x400, 0x10000400, 0x408, 0x10000408);
+	let pc2bytes10 = new Array(0, 0x20, 0, 0x20, 0x100000, 0x100020, 0x100000, 0x100020, 0x2000, 0x2020, 0x2000, 0x2020, 0x102000, 0x102020, 0x102000, 0x102020);
+	let pc2bytes11 = new Array(0, 0x1000000, 0x200, 0x1000200, 0x200000, 0x1200000, 0x200200, 0x1200200, 0x4000000, 0x5000000, 0x4000200, 0x5000200, 0x4200000, 0x5200000, 0x4200200, 0x5200200);
+	let pc2bytes12 = new Array(0, 0x1000, 0x8000000, 0x8001000, 0x80000, 0x81000, 0x8080000, 0x8081000, 0x10, 0x1010, 0x8000010, 0x8001010, 0x80010, 0x81010, 0x8080010, 0x8081010);
+	let pc2bytes13 = new Array(0, 0x4, 0x100, 0x104, 0, 0x4, 0x100, 0x104, 0x1, 0x5, 0x101, 0x105, 0x1, 0x5, 0x101, 0x105);
+
+	// how many iterations (1 for des, 3 for triple des)
+	let iterations = key.length > 8 ? 3 : 1; // changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys
+	// stores the return keys
+	let keys = new Array(32 * iterations);
+	// now define the left shifts which need to be done
+	let shifts = new Array(0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0);
+	// other variables
+	let lefttemp, righttemp, m = 0, n = 0, temp;
+
+	for (let j = 0; j < iterations; j++) { // either 1 or 3 iterations
+		let left = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++);
+		let right = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++);
+
+		temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
+		right ^= temp;
+		left ^= (temp << 4);
+		temp = ((right >>> -16) ^ left) & 0x0000ffff;
+		left ^= temp;
+		right ^= (temp << -16);
+		temp = ((left >>> 2) ^ right) & 0x33333333;
+		right ^= temp;
+		left ^= (temp << 2);
+		temp = ((right >>> -16) ^ left) & 0x0000ffff;
+		left ^= temp;
+		right ^= (temp << -16);
+		temp = ((left >>> 1) ^ right) & 0x55555555;
+		right ^= temp;
+		left ^= (temp << 1);
+		temp = ((right >>> 8) ^ left) & 0x00ff00ff;
+		left ^= temp;
+		right ^= (temp << 8);
+		temp = ((left >>> 1) ^ right) & 0x55555555;
+		right ^= temp;
+		left ^= (temp << 1);
+
+		// the right side needs to be shifted and to get the last four bits of the left side
+		temp = (left << 8) | ((right >>> 20) & 0x000000f0);
+		// left needs to be put upside down
+		left = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0);
+		right = temp;
+
+		// now go through and perform these shifts on the left and right keys
+		for (let i = 0; i < shifts.length; i++) {
+			// shift the keys either one or two bits to the left
+			if (shifts[i]) {
+				left = (left << 2) | (left >>> 26);
+				right = (right << 2) | (right >>> 26);
+			} else {
+				left = (left << 1) | (left >>> 27);
+				right = (right << 1) | (right >>> 27);
+			}
+			left &= -0xf;
+			right &= -0xf;
+
+			// now apply PC-2, in such a way that E is easier when encrypting or decrypting
+			// this conversion will look like PC-2 except only the last 6 bits of each byte are used
+			// rather than 48 consecutive bits and the order of lines will be according to
+			// how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7
+			lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf] |
+				pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(left >>> 16) & 0xf] |
+				pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf] |
+				pc2bytes6[(left >>> 4) & 0xf];
+			righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf] |
+				pc2bytes9[(right >>> 20) & 0xf] | pc2bytes10[(right >>> 16) & 0xf] |
+				pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf] |
+				pc2bytes13[(right >>> 4) & 0xf];
+			temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff;
+			keys[n++] = lefttemp ^ temp;
+			keys[n++] = righttemp ^ (temp << 16);
+		}
+	} // for each iterations
+	// return the keys we've created
+	return keys;
+} // end of des_createKeys
+function genkey (key, start, end) {
+	// 8 byte / 64 bit Key (DES) or 192 bit Key
+	return { key: pad(key.slice(start, end)), vector: 1 };
+}
+function pad (key) {
+	for (let i = key.length; i < 24; i++) {
+		key += '0';
+	}
+	return key;
+}
+
+let BASE64_MAPPING = [
+	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+	'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+	'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+	'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+	'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+	'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+	'w', 'x', 'y', 'z', '0', '1', '2', '3',
+	'4', '5', '6', '7', '8', '9', '+', '/'
+];
+
+/**
+ *ascii convert to binary
+ */
+let _toBinary = function (ascii) {
+	let binary = new Array();
+	while (ascii > 0) {
+		let b = ascii % 2;
+		ascii = Math.floor(ascii / 2);
+		binary.push(b);
+	}
+	/*
+	 var len = binary.length;
+	 if(6-len > 0){
+	 for(var i = 6-len ; i > 0 ; --i){
+	 binary.push(0);
+	 }
+	 } */
+	binary.reverse();
+	return binary;
+};
+
+/**
+ *binary convert to decimal
+ */
+let _toDecimal = function (binary) {
+	let dec = 0;
+	let p = 0;
+	for (let i = binary.length - 1; i >= 0; --i) {
+		let b = binary[i];
+		if (b === 1) {
+			dec += Math.pow(2, p);
+		}
+		++p;
+	}
+	return dec;
+};
+
+/**
+ *unicode convert to utf-8
+ */
+let _toUTF8Binary = function (c, binaryArray) {
+	let mustLen = (8 - (c + 1)) + ((c - 1) * 6);
+	let fatLen = binaryArray.length;
+	let diff = mustLen - fatLen;
+	while (--diff >= 0) {
+		binaryArray.unshift(0);
+	}
+	let binary = [];
+	let _c = c;
+	while (--_c >= 0) {
+		binary.push(1);
+	}
+	binary.push(0);
+	let i = 0, len = 8 - (c + 1);
+	for (; i < len; ++i) {
+		binary.push(binaryArray[i]);
+	}
+
+	for (let j = 0; j < c - 1; ++j) {
+		binary.push(1);
+		binary.push(0);
+		let sum = 6;
+		while (--sum >= 0) {
+			binary.push(binaryArray[i++]);
+		}
+	}
+	return binary;
+};
+
+let BASE64 = {
+	/**
+	 *BASE64 Encode
+	 */
+	encoder: function (str) {
+		let base64_Index = [];
+		let binaryArray = [];
+		for (var i = 0, len = str.length; i < len; ++i) {
+			let unicode = str.charCodeAt(i);
+			let _tmpBinary = _toBinary(unicode);
+			if (unicode < 0x80) {
+				let _tmpdiff = 8 - _tmpBinary.length;
+				while (--_tmpdiff >= 0) {
+					_tmpBinary.unshift(0);
+				}
+				binaryArray = binaryArray.concat(_tmpBinary);
+			} else if (unicode >= 0x80 && unicode <= 0x7FF) {
+				binaryArray = binaryArray.concat(_toUTF8Binary(2, _tmpBinary));
+			} else if (unicode >= 0x800 && unicode <= 0xFFFF) { // UTF-8 3byte
+				binaryArray = binaryArray.concat(_toUTF8Binary(3, _tmpBinary));
+			} else if (unicode >= 0x10000 && unicode <= 0x1FFFFF) { // UTF-8 4byte
+				binaryArray = binaryArray.concat(_toUTF8Binary(4, _tmpBinary));
+			} else if (unicode >= 0x200000 && unicode <= 0x3FFFFFF) { // UTF-8 5byte
+				binaryArray = binaryArray.concat(_toUTF8Binary(5, _tmpBinary));
+			} else if (unicode >= 4000000 && unicode <= 0x7FFFFFFF) { // UTF-8 6byte
+				binaryArray = binaryArray.concat(_toUTF8Binary(6, _tmpBinary));
+			}
+		}
+
+		let extra_Zero_Count = 0;
+		for (var i = 0, len = binaryArray.length; i < len; i += 6) {
+			let diff = (i + 6) - len;
+			if (diff === 2) {
+				extra_Zero_Count = 2;
+			} else if (diff === 4) {
+				extra_Zero_Count = 4;
+			}
+			// if(extra_Zero_Count > 0){
+			//  len += extra_Zero_Count+1;
+			// }
+			let _tmpExtra_Zero_Count = extra_Zero_Count;
+			while (--_tmpExtra_Zero_Count >= 0) {
+				binaryArray.push(0);
+			}
+			base64_Index.push(_toDecimal(binaryArray.slice(i, i + 6)));
+		}
+
+		let base64 = '';
+		for (var i = 0, len = base64_Index.length; i < len; ++i) {
+			base64 += BASE64_MAPPING[base64_Index[i]];
+		}
+
+		for (var i = 0, len = extra_Zero_Count / 2; i < len; ++i) {
+			base64 += '=';
+		}
+		return base64;
+	},
+	/**
+	 *BASE64  Decode for UTF-8
+	 */
+	decoder: function (_base64Str) {
+		let _len = _base64Str.length;
+		let extra_Zero_Count = 0;
+		/**
+		 *计算在进行BASE64编码的时候,补了几个0
+		 */
+		if (_base64Str.charAt(_len - 1) === '=') {
+			// alert(_base64Str.charAt(_len-1));
+			// alert(_base64Str.charAt(_len-2));
+			if (_base64Str.charAt(_len - 2) === '=') { // 两个等号说明补了4个0
+				extra_Zero_Count = 4;
+				_base64Str = _base64Str.substring(0, _len - 2);
+			} else { // 一个等号说明补了2个0
+				extra_Zero_Count = 2;
+				_base64Str = _base64Str.substring(0, _len - 1);
+			}
+		}
+
+		let binaryArray = [];
+		for (var i = 0, len = _base64Str.length; i < len; ++i) {
+			let c = _base64Str.charAt(i);
+			for (let j = 0, size = BASE64_MAPPING.length; j < size; ++j) {
+				if (c === BASE64_MAPPING[j]) {
+					let _tmp = _toBinary(j);
+					/* 不足6位的补0 */
+					let _tmpLen = _tmp.length;
+					if (6 - _tmpLen > 0) {
+						for (let k = 6 - _tmpLen; k > 0; --k) {
+							_tmp.unshift(0);
+						}
+					}
+					binaryArray = binaryArray.concat(_tmp);
+					break;
+				}
+			}
+		}
+
+		if (extra_Zero_Count > 0) {
+			binaryArray = binaryArray.slice(0, binaryArray.length - extra_Zero_Count);
+		}
+
+		let unicode = [];
+		let unicodeBinary = [];
+		for (var i = 0, len = binaryArray.length; i < len;) {
+			if (binaryArray[i] === 0) {
+				unicode = unicode.concat(_toDecimal(binaryArray.slice(i, i + 8)));
+				i += 8;
+			} else {
+				let sum = 0;
+				while (i < len) {
+					if (binaryArray[i] === 1) {
+						++sum;
+					} else {
+						break;
+					}
+					++i;
+				}
+				unicodeBinary = unicodeBinary.concat(binaryArray.slice(i + 1, i + 8 - sum));
+				i += 8 - sum;
+				while (sum > 1) {
+					unicodeBinary = unicodeBinary.concat(binaryArray.slice(i + 2, i + 8));
+					i += 8;
+					--sum;
+				}
+				unicode = unicode.concat(_toDecimal(unicodeBinary));
+				unicodeBinary = [];
+			}
+		}
+		// ---------直接转换为结果
+		let strResult = '';
+		for (var i = 0, len = unicode.length; i < len; ++i) {
+			strResult += String.fromCharCode(unicode[i]);
+		}
+		return strResult;
+	}
+};
+
+let rotateLeft = function (lValue, iShiftBits) {
+	return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
+};
+
+let addUnsigned = function (lX, lY) {
+	let lX4, lY4, lX8, lY8, lResult;
+	lX8 = (lX & 0x80000000);
+	lY8 = (lY & 0x80000000);
+	lX4 = (lX & 0x40000000);
+	lY4 = (lY & 0x40000000);
+	lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
+	if (lX4 & lY4) return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
+	if (lX4 | lY4) {
+		if (lResult & 0x40000000) return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
+		else return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
+	} else {
+		return (lResult ^ lX8 ^ lY8);
+	}
+};
+
+let F = function (x, y, z) {
+	return (x & y) | ((~x) & z);
+};
+
+let G = function (x, y, z) {
+	return (x & z) | (y & (~z));
+};
+
+let H = function (x, y, z) {
+	return (x ^ y ^ z);
+};
+
+let I = function (x, y, z) {
+	return (y ^ (x | (~z)));
+};
+
+let FF = function (a, b, c, d, x, s, ac) {
+	a = addUnsigned(a, addUnsigned(addUnsigned(F(b, c, d), x), ac));
+	return addUnsigned(rotateLeft(a, s), b);
+};
+
+let GG = function (a, b, c, d, x, s, ac) {
+	a = addUnsigned(a, addUnsigned(addUnsigned(G(b, c, d), x), ac));
+	return addUnsigned(rotateLeft(a, s), b);
+};
+
+let HH = function (a, b, c, d, x, s, ac) {
+	a = addUnsigned(a, addUnsigned(addUnsigned(H(b, c, d), x), ac));
+	return addUnsigned(rotateLeft(a, s), b);
+};
+
+let II = function (a, b, c, d, x, s, ac) {
+	a = addUnsigned(a, addUnsigned(addUnsigned(I(b, c, d), x), ac));
+	return addUnsigned(rotateLeft(a, s), b);
+};
+
+let convertToWordArray = function (string) {
+	let lWordCount;
+	let lMessageLength = string.length;
+	let lNumberOfWordsTempOne = lMessageLength + 8;
+	let lNumberOfWordsTempTwo = (lNumberOfWordsTempOne - (lNumberOfWordsTempOne % 64)) / 64;
+	let lNumberOfWords = (lNumberOfWordsTempTwo + 1) * 16;
+	let lWordArray = Array(lNumberOfWords - 1);
+	let lBytePosition = 0;
+	let lByteCount = 0;
+	while (lByteCount < lMessageLength) {
+		lWordCount = (lByteCount - (lByteCount % 4)) / 4;
+		lBytePosition = (lByteCount % 4) * 8;
+		lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));
+		lByteCount++;
+	}
+	lWordCount = (lByteCount - (lByteCount % 4)) / 4;
+	lBytePosition = (lByteCount % 4) * 8;
+	lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
+	lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
+	lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
+	return lWordArray;
+};
+
+let wordToHex = function (lValue) {
+	let WordToHexValue = '', WordToHexValueTemp = '', lByte, lCount;
+	for (lCount = 0; lCount <= 3; lCount++) {
+		lByte = (lValue >>> (lCount * 8)) & 255;
+		WordToHexValueTemp = '0' + lByte.toString(16);
+		WordToHexValue = WordToHexValue + WordToHexValueTemp.substr(WordToHexValueTemp.length - 2, 2);
+	}
+	return WordToHexValue;
+};
+
+let uTF8Encode = function (str) {
+	str = str.replace(/\x0d\x0a/g, '\x0a');
+	let output = '';
+	for (let n = 0; n < str.length; n++) {
+		let c = str.charCodeAt(n);
+		if (c < 128) {
+			output += String.fromCharCode(c);
+		} else if ((c > 127) && (c < 2048)) {
+			output += String.fromCharCode((c >> 6) | 192);
+			output += String.fromCharCode((c & 63) | 128);
+		} else {
+			output += String.fromCharCode((c >> 12) | 224);
+			output += String.fromCharCode(((c >> 6) & 63) | 128);
+			output += String.fromCharCode((c & 63) | 128);
+		}
+	}
+	return output;
+};
+
+var md5 = function (string) {
+	let x = Array();
+	let k, AA, BB, CC, DD, a, b, c, d;
+	let S11 = 7, S12 = 12, S13 = 17, S14 = 22;
+	let S21 = 5, S22 = 9, S23 = 14, S24 = 20;
+	let S31 = 4, S32 = 11, S33 = 16, S34 = 23;
+	let S41 = 6, S42 = 10, S43 = 15, S44 = 21;
+	string = uTF8Encode(string);
+	x = convertToWordArray(string);
+	a = 0x67452301;
+	b = 0xEFCDAB89;
+	c = 0x98BADCFE;
+	d = 0x10325476;
+	for (k = 0; k < x.length; k += 16) {
+		AA = a;
+		BB = b;
+		CC = c;
+		DD = d;
+		a = FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
+		d = FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
+		c = FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
+		b = FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
+		a = FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
+		d = FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
+		c = FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
+		b = FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
+		a = FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
+		d = FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
+		c = FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
+		b = FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
+		a = FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
+		d = FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
+		c = FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
+		b = FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
+		a = GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
+		d = GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
+		c = GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
+		b = GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
+		a = GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
+		d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
+		c = GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
+		b = GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
+		a = GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
+		d = GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
+		c = GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
+		b = GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
+		a = GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
+		d = GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
+		c = GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
+		b = GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
+		a = HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
+		d = HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
+		c = HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
+		b = HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
+		a = HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
+		d = HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
+		c = HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
+		b = HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
+		a = HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
+		d = HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
+		c = HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
+		b = HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
+		a = HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
+		d = HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
+		c = HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
+		b = HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
+		a = II(a, b, c, d, x[k + 0], S41, 0xF4292244);
+		d = II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
+		c = II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
+		b = II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
+		a = II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
+		d = II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
+		c = II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
+		b = II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
+		a = II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
+		d = II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
+		c = II(c, d, a, b, x[k + 6], S43, 0xA3014314);
+		b = II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
+		a = II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
+		d = II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
+		c = II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
+		b = II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
+		a = addUnsigned(a, AA);
+		b = addUnsigned(b, BB);
+		c = addUnsigned(c, CC);
+		d = addUnsigned(d, DD);
+	}
+	let tempValue = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
+	return tempValue.toLowerCase();
+};
+let base64EncodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+let base64DecodeChars = new Array(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
+/**
+ * base64编码
+ * @param {Object} str
+ */
+function base64encode (str) {
+	let out, i, len;
+	let c1, c2, c3;
+	len = str.length;
+	i = 0;
+	out = '';
+	while (i < len) {
+		c1 = str.charCodeAt(i++) & 0xff;
+		if (i === len) {
+			out += base64EncodeChars.charAt(c1 >> 2);
+			out += base64EncodeChars.charAt((c1 & 0x3) << 4);
+			out += '==';
+			break;
+		}
+		c2 = str.charCodeAt(i++);
+		if (i === len) {
+			out += base64EncodeChars.charAt(c1 >> 2);
+			out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
+			out += base64EncodeChars.charAt((c2 & 0xF) << 2);
+			out += '=';
+			break;
+		}
+		c3 = str.charCodeAt(i++);
+		out += base64EncodeChars.charAt(c1 >> 2);
+		out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
+		out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
+		out += base64EncodeChars.charAt(c3 & 0x3F);
+	}
+	return out;
+}
+/**
+ * base64解码
+ * @param {Object} str
+ */
+function base64decode (str) {
+	let c1, c2, c3, c4;
+	let i, len, out;
+	len = str.length;
+	i = 0;
+	out = '';
+	while (i < len) {
+		/* c1 */
+		do {
+			c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
+		}
+		while (i < len && c1 === -1);
+		if (c1 === -1) { break; }
+		/* c2 */
+		do {
+			c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
+		}
+		while (i < len && c2 === -1);
+		if (c2 === -1) { break; }
+		out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
+		/* c3 */
+		do {
+			c3 = str.charCodeAt(i++) & 0xff;
+			if (c3 === 61) { return out; }
+			c3 = base64DecodeChars[c3];
+		}
+		while (i < len && c3 === -1);
+		if (c3 === -1) { break; }
+		out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));
+		/* c4 */
+		do {
+			c4 = str.charCodeAt(i++) & 0xff;
+			if (c4 === 61) { return out; }
+			c4 = base64DecodeChars[c4];
+		}
+		while (i < len && c4 === -1);
+		if (c4 === -1) { break; }
+		out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
+	}
+	return out;
+}
+
+export default CryptoJS;

+ 80 - 0
src/api/http.js

@@ -0,0 +1,80 @@
+"use strict";
+import axios from "axios";
+import store from '@/store'
+import { ElMessage } from 'element-plus'
+import CryptoJS from './crypto'
+import {webLogin} from '@/utils/webLogin'
+
+// Full config:  https://github.com/axios/axios#request-config
+// axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
+// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
+// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
+
+let config = {
+  baseURL: import.meta.env.VITE_APP_API_URL,
+  timeout: 10*60 * 1000, // Timeout
+  // withCredentials: true, // Check cross-site Access-Control
+};
+
+const _axios = axios.create(config);
+
+_axios.interceptors.request.use(
+  function (config) {
+    // Do something before request is sent
+    config.headers.Authorization=store.state.token
+    return config;
+  },
+  function (error) {
+    // Do something with request error
+    return Promise.reject(error);
+  }
+);
+
+// Add a response interceptor
+_axios.interceptors.response.use(
+  function (response) {
+    // Do something with response data
+    let data
+    if(import.meta.env.MODE==='production'){
+      data=JSON.parse(CryptoJS.Des3Decrypt(response.data));//解密
+    }else{
+      data=response.data
+    }
+    if(data.code===401){//token失效
+      console.log('请重新登录')
+      console.log('miniprogram:',window.__wxjs_environment)
+      if(window.__wxjs_environment === 'miniprogram'){
+        // 如果在小程序中 则回跳到小程序首页进行更新token 再带回到项目中 
+        wx.miniProgram.switchTab({url: '/pages/report/report'})
+      }else{
+        webLogin()
+      }
+    }
+    if(data.code!==200&&data.code!==403&&data.code!==4001&&data.code!==401){
+      ElMessage.error(data.msg)
+    }
+    return data;
+  },
+  function (error) {
+    // Do something with response error
+    return Promise.reject(error);
+  }
+);
+
+/**
+ * 导出get请求方法
+ * @url 请求地址
+ * @params get请求参数
+ */
+export const get = (url, params) => {
+  return _axios.get(url, { params });
+};
+
+/**
+ * 导出post请求方法
+ * @url 请求地址
+ * @params post请求参数
+ */
+export const post = (url, params) => {
+  return _axios.post(url, params);
+};

+ 13 - 0
src/api/report.js

@@ -0,0 +1,13 @@
+/**
+ * 报告模块
+ */
+import {get,post} from './http'
+
+
+/**
+ * 研报详情
+ * @param report_id 
+ */
+export const apiReportDetail=params=>{
+    return get('/report/detail',params)
+}

BIN
src/assets/404.png


BIN
src/assets/bg-1.png


BIN
src/assets/bg-2.png


BIN
src/assets/bg-3.png


BIN
src/assets/bg-4.png


+ 3 - 0
src/assets/menu.svg

@@ -0,0 +1,3 @@
+<svg width="34" height="30" viewBox="0 0 34 30" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M0 0H34V4.28571H0V0ZM0 25.7143H21.25V30H0V25.7143ZM0 12.8571H34V17.1429H0V12.8571Z" fill="#666666"/>
+</svg>

+ 3 - 0
src/assets/search.svg

@@ -0,0 +1,3 @@
+<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M13.11 2.77996C10.23 -0.100043 5.55996 -0.130043 2.71996 2.71996C-0.130043 5.56996 -0.100043 10.23 2.77996 13.11C5.52996 15.86 9.90996 16.01 12.78 13.54L16.48 17.24C16.69 17.45 17.04 17.46 17.25 17.24C17.46 17.03 17.46 16.68 17.25 16.47L13.55 12.77C16.01 9.90996 15.86 5.52996 13.11 2.77996ZM12.4 12.4C9.96996 14.83 5.99996 14.8 3.54996 12.35C1.08996 9.88996 1.06996 5.91996 3.49996 3.49996C5.92996 1.07996 9.89996 1.09996 12.35 3.54996C14.8 5.99996 14.83 9.97996 12.4 12.4Z" fill="#333333"/>
+</svg>

+ 14 - 0
src/main.js

@@ -0,0 +1,14 @@
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from "./router";
+import ElementPlus from 'element-plus'
+import 'element-plus/dist/index.css'
+import 'normalize.css'
+import "@/style/global.scss";//全局样式
+
+
+const app = createApp(App)
+
+app.use(ElementPlus)
+app.use(router)
+app.mount('#app')

+ 59 - 0
src/router/index.js

@@ -0,0 +1,59 @@
+import { createRouter, createWebHistory } from "vue-router";
+/**
+ * 说明
+ * meta中 
+ * keepAlive表示是否要缓存  
+ */
+
+const routes=[
+  {
+    path: "/",
+    redirect: "/report/index"
+  },
+  {
+    path: "/report/index",
+    name: "ReportIndex",
+    component: ()=>import("@/views/report/Index.vue"),
+  },
+  {
+    path: "/report/search",
+    name: "ReportSearch",
+    component: ()=>import("@/views/report/Search.vue"),
+  },
+  {
+    path: "/report/detail",
+    name: "ReportDetail",
+    component: ()=>import("@/views/report/Detail.vue"),
+  },
+  
+  {
+    path: '/:pathMatch(.*)',
+    name: 'error',
+    component: () => import("@/views/404.vue"),
+    meta: { title: '404' },
+  }
+
+]
+
+const router=createRouter({
+  history:createWebHistory(import.meta.env.VITE_APP_BASE_URL),
+  routes,
+  scrollBehavior(to, from, savedPosition){
+    if (savedPosition&&to.meta.keepAlive) {
+      return savedPosition
+    } else {
+      return new Promise((resolve)=>{
+        setTimeout(() => {
+          resolve({left:0,top:0})
+        }, 0);
+      })
+    }
+  }
+})
+
+router.beforeEach((to, from, next) => {
+	next();
+})
+
+
+export default router

+ 132 - 0
src/style/global.scss

@@ -0,0 +1,132 @@
+// 全局样式
+// @font-face {
+//   font-family: 'PingFang';
+//   src: url('https://hzstatic.hzinsights.com/static/font/PingFangRegular.ttf');
+// }
+html,
+body,
+#app {
+  width: 100%;
+  height: 100%;
+  font-size: 16px;
+  color: #333;
+  // font-family: 'PingFang';
+  // min-width: 1024px;
+}
+
+:root{
+  --el-color-primary:#00459F;
+}
+
+// 禁止页面打印
+@media print{
+  body{
+    display: none;
+  }
+}
+
+//禁止复制文本
+.no-select-text{
+  user-select: none;
+  -moz-user-select:-moz-none;
+  moz-user-select: none;
+  -o-user-select:none;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  -khtml-user-select:none;
+}
+
+div {
+  box-sizing: border-box;
+}
+
+ul,
+li {
+  list-style-type: none;
+  margin: 0;
+  padding: 0;
+  box-sizing: border-box;
+}
+
+a {
+  text-decoration: none;
+}
+
+.flex {
+  display: flex;
+}
+
+.flex-row-center {
+  display: flex;
+  justify-content: center;
+}
+
+.flex-col-center {
+  display: flex;
+  align-items: center;
+}
+
+.flex-row-col-center {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.bg-white {
+  background-color: #fff;
+}
+
+img {
+  image-rendering: -moz-crisp-edges;
+  image-rendering: -o-crisp-edges;
+  image-rendering: -webkit-optimize-contrast;
+  image-rendering: crisp-edges;
+  -ms-interpolation-mode: nearest-neighbor;
+}
+
+// 清除浮动
+.clear-float::after {
+  content: "";
+  height: 0;
+  line-height: 0;
+  display: block;
+  visibility: hidden;
+  clear: both;
+}
+
+// 全局滚动条样式
+::-webkit-scrollbar {
+  width: 10px;
+  background-color: rgba(0, 0, 0, 0.05);
+}
+
+::-webkit-scrollbar-thumb {
+  background: #7a7a7a;
+  border-radius: 5px;
+}
+
+.el-image-viewer__canvas img {
+  background-color: #fff;
+}
+
+//单行省略
+.multi-ellipsis{
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+
+// 两行省略
+.multi-ellipsis-l2 {
+  display: -webkit-box;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  -webkit-line-clamp: 2;
+  -webkit-box-orient: vertical;
+}
+
+// 免责申明弹窗样式
+.disclaimers-box{
+  font-size: 16px;
+  line-height: 1.7;
+}

+ 18 - 0
src/views/404.vue

@@ -0,0 +1,18 @@
+<template>
+    <div class="nofound-page">
+        <img src="@/assets/404.png" alt="">
+        <p>404</p>
+    </div>
+</template>
+
+<style lang="scss" scoped>
+.nofound-page{
+    text-align: center;
+    font-size: 16px;
+    color: #666;
+    padding-top: 100px;
+    img{
+        width: 300px;
+    }
+}
+</style>

+ 195 - 0
src/views/report/Detail.vue

@@ -0,0 +1,195 @@
+<script setup>
+import {onMounted, ref} from 'vue'
+
+let showDisclaimers=ref(false)
+let wwidth=ref(0)
+onMounted(()=>{
+    wwidth.value=window.innerWidth
+})
+</script>
+
+<template>
+    <div class="report-detail-page">
+        <div class="header-wrap">
+            <div>
+                <span style="color:#00459F;margin-right:30px;">MORE REPORTS>></span>
+                <span>MACRO    COMMODITY</span>
+            </div>
+            <div style="color:#00459F;cursor: pointer;" @click="$router.replace('/')">ABOUT US</div>
+        </div>
+        <div class="mobile-header-wrap">
+            <span @click="$router.replace('/')">HORIZON INSIGHTS</span>
+        </div>
+        <div class="no-select-text detail-wrap">
+            <h2 class="title">【No.1|FICC】China Macro Digest (1124)</h2>
+            <p class="time">
+                <span>Horizon Insights FICC Team</span>
+                <span>Nov,23, 2022 09:49 PM </span>
+            </p>
+            <div class="abstract-box">
+                <div>Abstract:The sentiment of land market remains weak, constricting future real estate investment growth.</div>
+                <div class="notes">*Note: Please be sure to read the <span style="color:#00459F" @click="showDisclaimers=true">disclaimer</span></div>
+            </div>
+            <div class="overview-box">
+                <div class="label">Overview:</div>
+                <div>Real estate enterprises are still under the pressure from </div>
+            </div>
+            <div class="html-content"></div>
+        </div>
+    </div>
+    <!-- 免责申明 -->
+    <!-- 免责申明 -->
+    <el-dialog v-model="showDisclaimers" title="Disclaimers" center draggable :width="wwidth<800?'90%':'40%'">
+        <div class="disclaimers-box">
+            <div style="margin-bottom:10px">1、This report is only for the use of institutional clients officially signed by Hongze Midao (Shanghai) Investment Consulting Co., Ltd., and will not be regarded as clients only because the receiver/receiver receives this report.</div>
+            <div style="margin-bottom:10px">2、According to the international and industry prevailing standards, this report obtains such information through legal channels to ensure the reliability, accuracy and completeness as far as possible, but it does not guarantee the accuracy and completeness of the information described in the report, nor does it guarantee that the information or recommendations contained in this report will not change after the report is issued. The information provided in this report is for reference only.</div>
+            <div style="margin-bottom:10px">3、The contents of the report do not guarantee the final operation suggestions made by investors, nor do they make any written or oral commitment to share investment income or investment loss in any form. It does not serve as the final operational advice of the client in terms of investment, law, accounting or tax, nor as the moral, responsible and legal basis or voucher, regardless of whether it has been expressed or implied.</div>
+            <div style="margin-bottom:10px">4、In any case, the Company shall not be responsible for any loss caused by the use of the contents in the report by the customer/receiver/receiver, and the customer/receiver/receiver shall bear all risks.</div>
+        </div>
+    </el-dialog>
+</template>
+
+<style lang="scss" scoped>
+.report-detail-page{
+    padding: 0 20px;
+}
+@media (max-width: 768px){
+    .report-detail-page{
+        padding: 0;
+    }
+    .detail-wrap{
+        padding: 0 17px;
+    }
+}
+
+
+.header-wrap{
+    position: sticky;
+    top: 0;
+    border-bottom: 1px solid #E6E6E6;
+    padding: 44px 0;
+    display: flex;
+    justify-content: space-between;
+    font-size: 20px;
+    z-index: 99;
+}
+.mobile-header-wrap{
+    font-size: 17px;
+    box-shadow: 0px 4px 20px rgba(180, 180, 180, 0.16);
+    padding: 15px 0;
+    text-align: center;
+    font-weight: bold;
+    color: var(--el-color-primary);
+    border-bottom: 1px solid#E6E6E6;
+    position: sticky;
+    top: 0;
+    background-color: #fff;
+    z-index: 99;
+    display: none;
+}
+@media (max-width: 768px){
+    .header-wrap{
+        display: none;
+    }
+    .mobile-header-wrap{
+        display: block;
+    }
+}
+
+
+.detail-wrap{
+    padding-top: 40px;
+    .title{
+        font-size: 40px;
+        display: inline;
+        margin-left: -20px;
+    }
+    .time{
+        color: #999;
+        font-size: 18px;
+        margin-bottom: 60px;
+        margin-top: 30px;
+        span:first-child{
+            margin-right: 40px;
+        }
+    }
+    .abstract-box{
+        font-size: 18px;
+        position: relative;
+        padding-left: 24px;
+        .notes{
+            margin-top: 20px;
+        }
+        &::before{
+            content: '';
+            display: block;
+            position: absolute;
+            left: 0;
+            top: 0;
+            bottom: 0;
+            width: 4px;
+            background-color: var(--el-color-primary);
+        }
+    }
+    .overview-box{
+        margin-top: 40px;
+        padding: 20px;
+        background: rgba(77, 130, 191, 0.1);
+        border: 1px solid #E2E2E2;
+        .label{
+            font-size: 24px;
+            font-weight: 700;
+            margin-bottom: 20px;
+        }
+    }
+    .html-content{
+        line-height: 1.8;
+        font-size: 18px;
+        :deep(img){
+            width: 100% !important;
+        }
+        :deep(span){
+            font-size: 18px !important;
+            line-height: 1.8 !important;
+            background-color: rgba(255, 255, 255, 0) !important;
+        }
+        :deep(p){
+            font-size: 18px !important;
+            line-height: 1.8 !important;
+            background-color: rgba(255, 255, 255, 0) !important;
+        }
+        :deep(iframe){
+            width: 100% !important;
+        }
+    }
+}
+@media (max-width: 768px){
+    .detail-wrap{
+        padding-top: 20px;
+        .title{
+            font-size: 20px;
+            margin-left: -10px;
+        }
+        .time{
+            font-size: 14px;
+            margin-top: 15px;
+            margin-bottom: 30px;
+            span:first-child{
+                margin-right: 15px;
+            }
+        }
+        .abstract-box{
+            font-size: 14px;
+            padding-left: 15px;
+        }
+        .overview-box{
+            padding: 10px;
+            .label{
+                margin-bottom: 10px;
+                font-size: 16px;
+            }
+        }
+    }
+}
+
+</style>

+ 729 - 0
src/views/report/Index.vue

@@ -0,0 +1,729 @@
+<script setup>
+import {ref,reactive,computed} from 'vue'
+
+const demoArr=[
+            {
+                "Id": 0,
+                "ClassifyName": "ABOUT US",
+                "Sort": 0,
+                "ParentId": 0,
+                "CreateTime": "2022-11-01T17:44:20+08:00",
+                "ModifyTime": "2022-11-01T17:44:20+08:00",
+                "ClassifyLabel": "",
+                "ShowType": 0,
+                "IsShow": 1,
+                "Child": []
+            },
+            {
+                "Id": 8,
+                "ClassifyName": "PVC1",
+                "Sort": 0,
+                "ParentId": 0,
+                "CreateTime": "2022-11-01T17:04:22+08:00",
+                "ModifyTime": "2022-11-01T17:04:22+08:00",
+                "ClassifyLabel": "",
+                "ShowType": 0,
+                "IsShow": 1,
+                "Child": [
+                    {
+                        "Id": 9,
+                        "ClassifyName": "PVC(shandong)",
+                        "Sort": 2,
+                        "ParentId": 8,
+                        "CreateTime": "2022-11-01T16:48:37+08:00",
+                        "ModifyTime": "2022-11-01T16:48:37+08:00",
+                        "ClassifyLabel": "",
+                        "ShowType": 0,
+                        "IsShow": 1
+                    }
+                ]
+            },
+            {
+                "Id": 12,
+                "ClassifyName": "test",
+                "Sort": 1,
+                "ParentId": 0,
+                "CreateTime": "2022-11-01T13:59:54+08:00",
+                "ModifyTime": "2022-11-01T13:59:54+08:00",
+                "ClassifyLabel": "",
+                "ShowType": 0,
+                "IsShow": 1,
+                "Child": [
+                    {
+                        "Id": 19,
+                        "ClassifyName": "二级test",
+                        "Sort": 12,
+                        "ParentId": 12,
+                        "CreateTime": "2022-11-01T16:56:12+08:00",
+                        "ModifyTime": "2022-11-01T16:56:12+08:00",
+                        "ClassifyLabel": "",
+                        "ShowType": 0,
+                        "IsShow": 1
+                    }
+                ]
+            },
+            {
+                "Id": 1,
+                "ClassifyName": "Macro",
+                "Sort": 4,
+                "ParentId": 0,
+                "CreateTime": "2022-11-01T16:46:49+08:00",
+                "ModifyTime": "2022-11-01T16:46:49+08:00",
+                "ClassifyLabel": "",
+                "ShowType": 0,
+                "IsShow": 1,
+                "Child": [
+                    {
+                        "Id": 4,
+                        "ClassifyName": "China Macro and Commodity",
+                        "Sort": 0,
+                        "ParentId": 1,
+                        "CreateTime": "2022-10-20T17:45:52+08:00",
+                        "ModifyTime": "2022-10-20T17:45:52+08:00",
+                        "ClassifyLabel": "",
+                        "ShowType": 0,
+                        "IsShow": 1
+                    },
+                    {
+                        "Id": 3,
+                        "ClassifyName": "China Macro Weekly",
+                        "Sort": 0,
+                        "ParentId": 1,
+                        "CreateTime": "2022-10-24T17:43:48+08:00",
+                        "ModifyTime": "2022-10-24T17:43:48+08:00",
+                        "ClassifyLabel": "",
+                        "ShowType": 0,
+                        "IsShow": 1
+                    }
+                ]
+            }
+        ]
+
+let navList=ref(demoArr)
+
+let listState = reactive({
+    firstClassifyId:0,
+    firstClassifyName:'',
+    secClassifyId:0,
+    secClassifyOpt:[],
+
+    page:1,
+    pageSize:20,
+    list:[],
+    loading:false,
+    finished:false
+})
+// 切换一级分类
+function handleChangeFirstClassify(item){
+    showFilter.value=false
+    if(listState.firstClassifyId===item.Id) return
+    listState.firstClassifyId=item.Id
+    listState.firstClassifyName=item.ClassifyName
+    listState.secClassifyId=0
+    listState.secClassifyOpt=item.Child||[]
+}
+// 切换二级分类
+function handleChangeSecClassify(item,fitem){
+    showFilter.value=false
+    if(listState.secClassifyId===item.Id) return
+    listState.secClassifyId=item.Id
+    if(fitem){
+        listState.firstClassifyId=fitem.Id 
+        listState.firstClassifyName=fitem.ClassifyName
+    }
+    
+
+    
+    getList()
+}
+
+// 获取列表数据
+function getList(){
+    listState.loading=true
+    let arr=[]
+    if(listState.page<5){
+        for (let index = 0; index < 20; index++) {
+            arr.push('a')
+        }
+        listState.list=[...listState.list,...arr]
+    }else{
+        listState.finished=true
+    }
+    setTimeout(() => {
+        listState.loading=false
+    }, 300);
+}
+
+// 监听页面滚动
+function listenScroll(){
+    window.onscroll=(e)=>{
+        if(listState.firstClassifyId===0) return
+        if(listState.loading||listState.finished) return
+        const scrollTop = document.documentElement.scrollTop||document.body.scrollTop;
+        const windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
+        const scrollHeight = document.documentElement.scrollHeight||document.body.scrollHeight;
+        if(scrollTop+windowHeight>=scrollHeight){   //考虑到滚动的位置一般可能会大于一点可滚动的高度,所以这里不能用等于
+            console.log("距顶部"+scrollTop+"可视区高度"+windowHeight+"滚动条总高度"+scrollHeight);
+            listState.page++
+            getList()
+        }   
+    }
+}
+listenScroll()
+
+// 弹窗筛选
+let showFilter=ref(false)
+let filterSize=ref('30%')
+</script>
+
+<template>
+    <div class="report-index-page">
+        <div class="header-wrap">
+            <img class="menu-icon" @click="showFilter=true;filterSize='100%'" src="@/assets/menu.svg" alt="">
+            <span>HORIZON INSIGHTS</span>
+            <div class="search-box" @click="$router.push('/report/search')">
+                <img src="@/assets/search.svg" alt="">
+                <span style="margin-left:10px">search for</span>
+            </div>
+        </div>
+        <div class="content-wrap">
+        <div class="nav-wrap">
+            <img class="menu-icon" @click="showFilter=true;filterSize='30%'" src="@/assets/menu.svg" alt="">
+            <span 
+                :class="['nav-item',item.Id===listState.firstClassifyId?'active':'']" 
+                v-for="item in navList" 
+                :key="item.Id"
+                @click="handleChangeFirstClassify(item)"
+            >{{item.ClassifyName}}</span>
+        </div>
+        <div class="sub-nav-wrap">
+            <h2 class="label">{{listState.firstClassifyName}}</h2>
+            <div class="sub-nav-list">
+                <span 
+                    :class="['item',item.Id===listState.secClassifyId?'active':'']" 
+                    v-for="item in listState.secClassifyOpt" 
+                    :key="item.Id"
+                    @click="handleChangeSecClassify(item)"
+                >{{item.ClassifyName}}</span>
+            </div>
+        </div>
+        <!-- 固定展示的报告区域 -->
+        <div class="fix-report-wrap" v-show="listState.firstClassifyId!=0&&listState.secClassifyId===0">
+            <div class="left-wrap">
+                <div class="report-item-normal">
+                    <div class="title">China Iron Ore Express</div>
+                    <div class="intro">PLA Eastern Theater Command’s J-10C fighters hold interception exercise in far sea, show growing skills</div>
+                    <div class="time">23, 2022 09:49 PM </div>
+                </div>
+                <div class="report-item-normal">
+                    <div class="title">China Iron Ore Express</div>
+                    <div class="intro">PLA Eastern Theater Command’s J-10C fighters hold interception exercise in far sea, show growing skills</div>
+                    <div class="time">23, 2022 09:49 PM </div>
+                </div>
+                <div class="report-item-normal">
+                    <div class="title">China Iron Ore Express</div>
+                    <div class="intro">PLA Eastern Theater Command’s J-10C fighters hold interception exercise in far sea, show growing skills</div>
+                    <div class="time">23, 2022 09:49 PM </div>
+                </div>
+                <img class="img" src="@/assets/bg-2.png" alt="">
+            </div>
+            <div class="center-wrap">
+                <img class="img-top" src="@/assets/bg-3.png" alt="">
+                <div class="report-item-normal">
+                    <div class="title">China Iron Ore Express</div>
+                    <div class="intro">PLA Eastern Theater Command’s J-10C fighters hold interception exercise in far sea, show growing skills</div>
+                    <div class="time">23, 2022 09:49 PM </div>
+                </div>
+                <div class="bot-box">
+                    <div class="report-item-small">
+                        <div class="title">China Iron Ore Express</div>
+                        <div class="intro">PLA Eastern EasternEasternEastern Theater Command’s J-10C fighters hold interception exercise in far sea, show growing skills</div>
+                        <div class="time">23, 2022 09:49 PM </div>
+                    </div>
+                    <img class="img-bot" src="@/assets/bg-4.png" alt="">
+                </div>
+            </div>
+            <div class="right-wrap">
+                <div class="report-item-normal" v-for="item in 4" :key="item">
+                    <div class="title">China Iron Ore Express</div>
+                    <div class="intro">PLA Eastern Theater Command’s J-10C fighters hold interception exercise in far sea, show growing skills</div>
+                    <div class="time">23, 2022 09:49 PM </div>
+                </div>
+            </div>
+        </div>
+        <!-- 报告列表 -->
+        <div class="report-list-wrap" v-show="listState.firstClassifyId!=0">
+            <div class="item" v-for="item,index in listState.list" :key="index">
+                <div class="title">title</div>
+                <div class="intro">PLA Eastern Theater Command’s J-10C fighters hold interception exercise in far sea, show growing skills, confidence</div>
+                <div class="time">23, 2022 09:49 PM </div>
+            </div>
+        </div>
+
+        <!-- 关于 我们 -->
+        <div class="about-us-box" v-show="listState.firstClassifyId==0">
+            <div class="flex box top-box">
+                <div class="left">
+                    <video controls autoplay src="https://hongze.oss-cn-shanghai.aliyuncs.com/static/video_03.mp4"></video>
+                </div>
+                <div class="right">
+                    <div class="con">
+                        <div>ABOUT US</div>
+                        <p>Horizon Insights is the largest independent investment research house in China. We offer unrivaled market intelligence on China’s economy, real estate, and industry changes through on-the-ground surveys and market analysis. Our commodities coverage includes ferrous, non-ferrous, crude oil, and chemicals.</p>
+                    </div>
+                    
+                </div>
+            </div>
+            <div class="flex box bot-box">
+                <div class="left">
+                    <div class="con">
+                        <h2>CONTACT US</h2>
+                        <div>Website: https://www.hzinsights.com/en</div>
+                        <div>Email: myyu@hzinsights.com</div>
+                        <div>
+                            Shanghai Office: Suite 1206, 12/F, 210 Century Avenue, Shanghai, 200120<br>
+                            U.S. Office: 708 Main Street 6 Floor, Houston, Texas 77002<br>
+                            Singapore Office: 28 Beach Road, #25-03, Singapore 189762
+                        </div>
+                    </div>
+                </div>
+                <div class="right">
+                    <img src="@/assets/bg-1.png" alt="">
+                </div>
+            </div>
+        </div>
+        </div>
+    </div>
+    <!-- 筛选 -->
+    <el-drawer
+        v-model="showFilter"
+        direction="ltr"
+        :size="filterSize"
+        class="self-drawer-box"
+    >
+        <div class="filter-wrap">
+            <div class="item" v-for="item in navList" :key="item.Id">
+                <span  class="title" @click="handleChangeFirstClassify(item)">{{item.ClassifyName}}</span>
+                <div class="text" v-for="_item in item.Child" :key="_item.Id" @click="handleChangeSecClassify(_item,item)">{{_item.ClassifyName}}</div>
+            </div>
+        </div>
+    </el-drawer>
+</template>
+
+<style lang="scss">
+.self-drawer-box{
+
+    .el-drawer__header{
+        margin-bottom: 0;
+    }
+}
+</style>
+<style lang="scss" scoped>
+.report-index-page{
+    padding: 0 20px;
+}
+@media (max-width: 768px){
+    .report-index-page{
+        padding: 0 ;
+    }
+    .content-wrap{
+        padding: 0 20px;
+    }
+}
+
+
+.header-wrap{
+    text-align: center;
+    font-size: 40px;
+    font-weight: bold;
+    color: var(--el-color-primary);
+    padding: 40px 0;
+    border-bottom: 1px solid#E6E6E6;
+    position: sticky;
+    top: 0;
+    background-color: #fff;
+    z-index: 99;
+    .search-box{
+        position: absolute;
+        top: 50%;
+        transform: translateY(-50%);
+        right: 20px;
+        font-size: 16px;
+        color: #333;
+        font-weight: 500;
+        cursor: pointer;
+        span,img{
+            vertical-align: middle;
+        }
+    }
+    .menu-icon{
+        position: absolute;
+        left: 20px;
+        top: 50%;
+        transform: translateY(-50%);
+        display: none;
+    }
+}
+@media (max-width: 768px){
+    .header-wrap{
+        border: none;
+        font-size: 17px;
+        box-shadow: 0px 4px 20px rgba(180, 180, 180, 0.16);
+        padding: 15px 0;
+        .search-box{
+            span{
+                display: none;
+            }
+        }
+        .menu-icon{
+            display: block;
+            width: 17px;
+        }
+    }
+}
+
+.nav-wrap{
+    padding: 15px 20px 19px 20px;
+    border-bottom: 1px solid#E6E6E6;
+    position: sticky;
+    top: 127px;
+    background-color: #fff;
+    z-index: 99;
+    .menu-icon{
+        width: 13px;
+        cursor: pointer;
+    }
+    .nav-item{
+        color: #666;
+        font-size: 16px;
+        display: inline-block;
+        margin-left: 40px;
+        cursor: pointer;
+        position: relative;
+        &.active::after{
+            display: block;
+            content: '';
+            position: absolute;
+            bottom: -19px;
+            width: 100%;
+            height: 4px;
+            background-color: var(--el-color-primary);
+        }
+        &:hover{
+            color: var(--el-color-primary);
+        }
+    }
+}
+@media (max-width: 768px){
+    .nav-wrap{
+        display: none;
+    }
+}
+
+.sub-nav-wrap{
+    .label{
+        font-size: 34px;
+    }
+    .sub-nav-list{
+        .item{
+            display: inline-block;
+            margin-right: 30px;
+            margin-bottom: 20px;
+            font-size: 16px;
+            color: #666;
+            cursor: pointer;
+            &:hover{
+                color: var(--el-color-primary);
+            }
+            &.active{
+                color: var(--el-color-primary);
+            }
+        }
+    }
+}
+@media (max-width: 768px){
+    .sub-nav-wrap{
+        display: none;
+    }
+}
+
+.about-us-box{
+    background: #2C2E33;
+    margin-top: 40px;
+    .box{
+        .left{
+            flex: 2;
+        }
+        .right{
+            flex: 1;
+        }
+    }
+    .top-box{
+        .left{
+            background: #000;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            video{
+                object-fit: contain;
+                width: 100%;
+                display: block;
+            }
+        }
+        .right{
+            .con{
+                padding: 60px 40px 40px 40px;
+            }
+            color: #fff;
+            div{
+                font-size: 30px;
+                font-weight: bold;
+            }
+            p{
+                font-size: 18px;
+                line-height: 1.7;
+                font-weight: 500;
+            }
+        }
+    }
+    .bot-box{
+        .right{
+            background-color: #000;
+            img{
+                width: 100%;
+                height: 100%;
+                object-fit: cover;
+                display: block;
+            }
+        }
+        .left{
+            .con{
+                padding: 30px;
+            }
+            color: #fff;
+            h2{
+                font-size: 30px;
+            }
+            div{
+                line-height: 1.7;
+            }
+        }
+    }
+}
+@media (max-width: 768px){
+    .about-us-box{
+        background-color: #fff;
+        .top-box{
+            flex-direction: column;
+            .left{
+                flex: 1;
+            }
+            .right{
+                flex: 1;
+                color: #333;
+                .con{
+                    padding: 20px 17px;
+                }
+                div{
+                    font-size: 16px;
+                }
+                p{
+                    color: #666;
+                    font-size: 14px;
+                }
+            }
+        }
+        .bot-box{
+            flex-direction: column-reverse;
+            .right{
+                background-color: #fff;
+                flex: 1;
+            }
+            .left{
+                .con{
+                    padding: 20px 17px;
+                }
+                flex: 1;
+                color: #666;
+                font-size: 14px;
+                h2{
+                    color: #333;
+                    font-size: 16px;
+                }
+            }
+        }
+    }
+}
+
+.filter-wrap{
+    .item{
+        margin-bottom: 50px;
+        .title{
+            font-size: 28px;
+            font-weight: bold;
+            margin-bottom: 30px;
+            display: block;
+            cursor: pointer;
+        }
+        .text{
+            cursor: pointer;
+            font-size: 18px;
+            margin-bottom: 20px;
+            &:hover{
+                color: var(--el-color-primary);
+            }
+        }
+    }
+}
+
+.fix-report-wrap{
+    margin-top: 30px;
+    border-top: 1px solid #E6E6E6;
+    border-bottom: 1px solid #E6E6E6;
+    padding: 20px 0;
+    display: flex;
+    .report-item-normal{
+        border-bottom: 1px solid #E6E6E6;
+        padding: 20px 0;
+        .title{
+            font-size: 20px;
+            font-weight: 600;
+            overflow: hidden;
+            white-space: nowrap;
+            text-overflow: ellipsis;
+        }
+        .intro{
+            font-size: 14px;
+            color: #666;
+            margin: 10px 0;
+            line-height: 17px;
+            min-height: 30px;
+            display: -webkit-box;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            -webkit-line-clamp: 2;
+            -webkit-box-orient: vertical;
+        }
+        .time{
+            font-size: 14px;
+            color: #999;
+        }
+    }
+    .left-wrap,.center-wrap,.right-wrap{
+        width: 33.33%;
+    }
+    .left-wrap{
+        padding-right: 40px;
+        .img{
+            width: 100%;
+            margin-top: 20px;
+        }
+    }
+    .right-wrap{
+        padding-left: 40px;
+        .report-item-normal{
+            .intro{
+                -webkit-line-clamp: 3;
+                min-height: 45px;
+            }
+            &:last-child{
+                border: none;
+            }
+        }
+    }
+    .center-wrap{
+        border-left: 1px solid #E6E6E6;
+        border-right: 1px solid #E6E6E6;
+        padding: 0 20px;
+        .img-top{
+            width: 100%;
+        }
+        .report-item-normal{
+            .intro{
+                -webkit-line-clamp: 3;
+                min-height: 45px;
+            }
+        }
+        .bot-box{
+            margin-top: 20px;
+            display: flex;
+            .report-item-small{
+                width: 50%;
+                padding-right: 20px;
+                .title{
+                    font-size: 20px;
+                    font-weight: 600;
+                    display: -webkit-box;
+                    overflow: hidden;
+                    text-overflow: ellipsis;
+                    -webkit-line-clamp: 2;
+                    -webkit-box-orient: vertical;
+                }
+                .intro{
+                    font-size: 14px;
+                    color: #666;
+                    margin: 20px 0;
+                    line-height: 1.7;
+                    min-height: 140px;
+                    display: -webkit-box;
+                    overflow: hidden;
+                    text-overflow: ellipsis;
+                    -webkit-line-clamp: 6;
+                    -webkit-box-orient: vertical;
+                }
+                .time{
+                    font-size: 14px;
+                    color: #999;
+                }
+            }
+            .img-bot{
+                width: 50%;
+            }
+        }
+    }
+
+    
+}
+@media (max-width: 768px){
+    .fix-report-wrap{
+        display: none;
+    }
+}
+
+.report-list-wrap{
+    .item{
+        padding: 20px 0;
+        border-top: 1px solid #E6E6E6;
+        .title{
+            font-size: 20px;
+            font-weight: 600;
+        }
+        .intro{
+            font-size: 14px;
+            color: #666;
+            margin-top: 10px;
+            margin-bottom: 20px;
+        }
+        .time{
+            font-size: 14px;
+            color: #999;
+        }
+    }
+}
+@media (max-width: 768px){
+    .report-list-wrap{
+        .item{
+            padding: 10px 0;
+            .title{
+                font-size: 14px;
+            }
+            .intro{
+                margin-bottom: 10px;
+            }
+            .time{
+                font-size: 12px;
+            }
+        }
+    }
+}
+</style>

+ 117 - 0
src/views/report/Search.vue

@@ -0,0 +1,117 @@
+<script setup>
+import {reactive} from 'vue'
+import { Search } from '@element-plus/icons-vue'
+
+let listState=reactive({
+    keywords:'',
+
+})
+</script>
+
+<template>
+    <div class="report-search-page">
+        <div class="header-wrap" @click="$router.replace('/')">
+            <span>HORIZON INSIGHTS</span>
+        </div>
+        <div class="search-box">
+            <el-input
+                v-model="listState.keywords"
+                class="self-input"
+                placeholder="Please Input Keywords"
+                :suffix-icon="Search"
+            />
+        </div>
+        <div class="report-list-wrap">
+            <div class="item">
+                <div class="title">title</div>
+                <div class="intro">intro</div>
+                <div class="time">Nov,23, 2022 09:49 PM</div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<style lang="scss" scoped>
+.header-wrap{
+    text-align: center;
+    font-size: 40px;
+    font-weight: bold;
+    color: var(--el-color-primary);
+    padding: 40px 0;
+    border-bottom: 1px solid#E6E6E6;
+    position: sticky;
+    top: 0;
+    background-color: #fff;
+    z-index: 99;
+}
+@media (max-width: 768px){
+    .header-wrap{
+        border: none;
+        font-size: 17px;
+        box-shadow: 0px 4px 20px rgba(180, 180, 180, 0.16);
+        padding: 15px 0;
+    }
+}
+
+.search-box{
+    width: 640px; 
+    margin: 60px auto 0 auto;
+    .self-input{
+        :deep(.el-input__wrapper){
+            border-radius: 24px;
+            border: 1px solid #000000;
+            height: 48px;
+        }
+    }
+}
+@media (max-width: 768px){
+    .search-box{
+        width: calc(100vw - 34px);
+        margin: 30px auto 0 auto;
+        .self-input{
+            :deep(.el-input__wrapper){
+                height: 40px;
+            }
+        }
+    }
+}
+
+.report-list-wrap{
+    width: 600px;
+    margin: 50px auto;
+    .item{
+        border-bottom: 1px solid #E6E6E6;
+        padding: 20px 0;
+        .title{
+            font-size: 20px;
+            font-weight: 600;
+        }
+        .intro{
+            font-size: 14px;
+            color: #666;
+            line-height: 17px;
+            margin: 10px 0;
+        }
+        .time{
+            font-size: 14px;
+            color: #999;
+        }
+    }
+}
+@media (max-width: 768px){
+    .report-list-wrap{
+        width: 100%;
+        padding: 0 17px;
+        margin: 25px 0;
+        .item{
+            padding: 10px 0;
+            .title{
+                font-size: 14px;
+            }
+            .time{
+                font-size: 12px;
+            }
+        }
+    }
+}
+</style>

+ 17 - 0
vite.config.js

@@ -0,0 +1,17 @@
+import { defineConfig,loadEnv } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import path from "path";
+
+// https://vitejs.dev/config/
+export default ({mode})=> defineConfig({
+  base: loadEnv(mode,process.cwd()).VITE_APP_BASE_URL,// 若服务器不是将该项目放在根目录的则 需要此设置 和服务器上同名
+  plugins: [vue()],
+  resolve: {
+    alias: {
+      "@": path.resolve(__dirname, "./src"),
+    },
+  },
+  build:{
+    outDir:loadEnv(mode, process.cwd()).VITE_APP_OUTDIR
+  },
+})