Browse Source

投屏教程,帮助中心

liushengqiang 2 years ago
parent
commit
fc040e8a49

+ 1 - 1
.gitignore

@@ -6,7 +6,7 @@ yarn-debug.log*
 yarn-error.log*
 pnpm-debug.log*
 lerna-debug.log*
-
+osmd-extended
 node_modules
 dist
 dist-ssr

+ 2 - 2
package.json

@@ -1,10 +1,10 @@
 {
-  "name": "cloud-exercise",
+  "name": "music-score",
   "private": true,
   "version": "0.0.0",
   "scripts": {
     "dev": "vite --host --force",
-    "build": "vue-tsc && vite build",
+    "build": "vite build",
     "preview": "vite preview --open"
   },
   "dependencies": {

+ 7 - 2
src/page-gym/api.ts

@@ -36,5 +36,10 @@ export const sysMusicScoreCategoriesQueryTree = (enable = false) => {
 
 /** 获取曲谱列表 */
 export const sysMusicScoreQueryPage2 = (params: any) => {
-	return request.get(`/sysMusicScore/queryPage2`, {params})
-}
+	return request.get(`/sysMusicScore/queryPage2`, { params });
+};
+
+/** 提交意见反馈 */
+export const suggestionAdd = (data: any) => {
+	return request.post("/suggestion/add", { data });
+};

+ 12 - 0
src/page-gym/helper-model/icons/close2.svg

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g transform="translate(-493.000000, -57.000000)" fill="#01C1B5" fill-rule="nonzero">
+            <g transform="translate(143.000000, 40.000000)">
+                <g transform="translate(350.000000, 17.000000)">
+                    <path d="M1.05548433,1.07092551 L0.973890205,1.16134969 C0.666012474,1.54828454 0.694001358,2.11481906 1.05785686,2.46909941 L6.537,7.949 L1.05548433,13.4315873 C0.672191496,13.8148801 0.672191496,14.4441272 1.05548433,14.8274201 L1.08636669,14.8583024 L1.17896103,14.9399506 C1.56501142,15.2393273 2.12839072,15.2121112 2.48219949,14.8583024 L7.964,9.376 L13.4470285,14.8583024 C13.8303213,15.2415953 14.4595684,15.2415953 14.8428613,14.8583024 L14.8737436,14.8274201 L14.9553918,14.7348257 C15.2547684,14.3487753 15.2275524,13.785396 14.8737436,13.4315873 L9.391,7.949 L14.8737436,2.46675831 C15.2570364,2.08346548 15.2570364,1.45421835 14.8737436,1.07092551 L14.8428613,1.04004316 L14.7502669,0.958394979 C14.3642165,0.659018325 13.8008372,0.686234384 13.4470285,1.04004316 L7.964,6.53 L2.48231995,1.0401637 C2.09890665,0.65675032 1.46965952,0.65675032 1.08636669,1.04004316 L1.05548433,1.07092551 Z" id="路径"></path>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

BIN
src/page-gym/helper-model/icons/icon-right-back.png


+ 3 - 0
src/page-gym/helper-model/index.module.less

@@ -13,4 +13,7 @@
             opacity: .8;
         }
     }
+}
+.screen{
+    overflow: initial;
 }

+ 19 - 14
src/page-gym/helper-model/index.tsx

@@ -10,32 +10,37 @@ export default defineComponent({
 	setup() {
 		const helperData = reactive({
 			show: false,
-            recommendationShow: false, // 建议
+			recommendationShow: false, // 建议
 		});
 		return () => (
 			<>
-				<div class={styles.helperModel} onClick={() => (helperData.recommendationShow = true)}>
+				<div class={styles.helperModel} onClick={() => (helperData.show = true)}>
 					<img src={iconRight} />
 				</div>
 				<Popup
-                    class="van-custom"
+					class={["van-custom", styles.screen]}
 					v-model:show={helperData.show}
 					onClose={() => {
 						helperData.show = false;
 					}}
-                    position="right"
+					position="right"
 				>
-					<ScreenModel />
+					<ScreenModel
+						onClose={(open: Boolean) => {
+							if (open) {
+								helperData.recommendationShow = true;
+							} else {
+								helperData.show = false;
+							}
+						}}
+					/>
 				</Popup>
-				<Popup
-					v-model:show={helperData.recommendationShow}
-					onClose={() => {
-                        helperData.recommendationShow = false;
-					}}
-                    class="van-custom van-scale"
-                    transition="van-scale"
-				>
-					<Recommendation />
+				<Popup v-model:show={helperData.recommendationShow} class="van-custom van-scale" transition="van-scale">
+					<Recommendation
+						onClose={() => {
+							helperData.recommendationShow = false;
+						}}
+					/>
 				</Popup>
 			</>
 		);

+ 81 - 4
src/page-gym/helper-model/recommendation/index.module.less

@@ -1,6 +1,83 @@
-.container{
-    width: 46vw;
-    height: 80vh;
-    background: #fff;
+
+.closeBtn {
+    position: absolute;
+    right: -34px;
+    top: -6px;
+    width: 24px;
+    height: 24px;
+    border-radius: 50%;
+    background-color: #fff;
+    overflow: hidden;
+    padding: 6px;
+
+    img {
+        width: 100%;
+        height: 100%;
+        display: block;
+    }
+
+    &:active {
+        opacity: .8;
+    }
+}
+
+.content {
+    position: relative;
     border-radius: 8px;
+    width: 300px;
+    // height: 90vh;
+    max-height: 370px;
+    background-color: #fff;
+    --van-tabs-line-height: 42px;
+    overflow: hidden;
+    :global {
+        .van-tabs__wrap{
+            border-bottom: 1Px solid #F0F0F0;
+        }
+        .van-tabs__content {
+            max-height: calc(90vh - var(--van-tabs-line-height));
+            overflow-y: auto;
+
+            &::-webkit-scrollbar {
+                width: 0;
+                display: none;
+            }
+        }
+        .van-field{
+            font-size: 12Px;
+            line-height: 16Px;
+        }
+    }
+}
+
+.tags {
+    display: flex;
+    justify-content: space-between;
+    text-align: center;
+    flex-wrap: wrap;
+    padding: 0 var(--van-cell-horizontal-padding) var(--van-cell-vertical-padding) var(--van-cell-horizontal-padding);
+    >span {
+        margin: 3px 0;
+        border-radius: 3PX;
+        display: block;
+        width: 30%;
+        font-size: 12PX;
+        padding: 6PX 0;
+        background-color: #F8F8F8;
+        color: #999999;
+        border: 1PX solid #F8F8F8;
+
+        &.active {
+            color: var(--van-primary-color);
+            border-color: var(--van-primary-color);
+            background-color: #E2FFF9;
+            pointer-events: none;
+        }
+    }
+}
+.btn{
+    width: 80%;
+    height: 30px;
+    font-size: 13px;
+    margin: 0 auto;
 }

+ 77 - 9
src/page-gym/helper-model/recommendation/index.tsx

@@ -1,11 +1,79 @@
-import { defineComponent } from "vue";
-import styles from './index.module.less'
+import { defineComponent, reactive, ref } from "vue";
+import styles from "./index.module.less";
+import iconClose from "../icons/close2.svg";
+import { Button, Cell, Field, Tab, Tabs, showToast } from "vant";
+import { suggestionAdd } from "../../api";
 
 export default defineComponent({
-    name: 'recommendation',
-    setup(props, ctx) {
-        return () => <div class={styles.container}>
-            
-        </div>
-    },
-})
+	name: "recommendation",
+	emits: ["close"],
+	setup(props, { emit }) {
+		const tags = ["识别不准", "无法评测", "不出评测结果", "曲谱不一致", "指法错误", "其他"];
+		const recommenData = reactive({
+			loading: false,
+			active: "识别不准",
+			message: "",
+		});
+
+		/** 提交意见反馈 */
+		const handleSubmit = async () => {
+			if (!recommenData.message) {
+				showToast({
+					message: "请先填写意见反馈",
+					position: "top",
+				});
+				return;
+			}
+			recommenData.loading = true;
+			try {
+				await suggestionAdd({
+					content: recommenData.message + "#" + recommenData.active,
+					type: "SMART_PRACTICE",
+				});
+				showToast({
+					message: "意见反馈已提交",
+					position: "top",
+				});
+                emit('close')
+			} catch (error) {}
+			recommenData.loading = false;
+		};
+
+		return () => (
+			<>
+				<div class={styles.closeBtn} onClick={() => emit("close")}>
+					<img src={iconClose} />
+				</div>
+				<div class={styles.content}>
+					<Tabs lineHeight={0} color="#1A1A1A">
+						<Tab title="意见反馈">
+							<Cell border={false} title="请选择问题类型" />
+							<div class={styles.tags}>
+								{tags.map((text) => (
+									<span class={[styles.tag, recommenData.active === text && styles.active]} onClick={() => (recommenData.active = text)}>
+										{text}
+									</span>
+								))}
+							</div>
+							<Field
+								v-model={recommenData.message}
+								rows="3"
+								autosize={{ maxHeight: 128 }}
+								border={false}
+								type="textarea"
+								maxlength={200}
+								placeholder="请详细描述您遇到的问题,以便我们尽快为您解决!"
+								show-word-limit
+							/>
+							<Cell>
+								<Button loading={recommenData.loading} class={styles.btn} block round type="primary" onClick={handleSubmit}>
+									提交反馈
+								</Button>
+							</Cell>
+						</Tab>
+					</Tabs>
+				</div>
+			</>
+		);
+	},
+});

+ 55 - 1
src/page-gym/helper-model/screen-model/index.module.less

@@ -1,7 +1,61 @@
-.container{
+.container {
+    position: relative;
     width: 40vw;
     height: 100vh;
     max-width: 295px;
     background: #fff;
     border-radius: 16px 0 0 16px;
+    overflow-y: auto;
+
+    &::-webkit-scrollbar {
+        width: 0;
+        display: none;
+    }
+
+    :global {
+        .van-tabs__content {
+            height: calc(100vh - var(--van-tabs-line-height));
+        }
+
+        .van-tab__panel {
+            display: flex;
+            flex-direction: column;
+            width: 100%;
+            height: 100%;
+        }
+
+        iframe {
+            flex: 1;
+            width: 100%;
+            border: none;
+            margin: 0;
+
+            &::-webkit-scrollbar {
+                width: 0;
+                display: none;
+            }
+        }
+    }
+}
+
+.closeBtn {
+    position: absolute;
+    left: -30px;
+    top: 50%;
+    margin-top: -20px;
+    width: 30px;
+    height: 40px;
+}
+.jianyi{
+    flex-shrink: 0;
+    height: 50px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    color: var(--van-primary-color);
+    border-top: 1px solid #F0F0F0;
+    font-size: 13px;
+    &:active{
+        opacity: .8;
+    }
 }

+ 27 - 7
src/page-gym/helper-model/screen-model/index.tsx

@@ -1,9 +1,29 @@
-import { defineComponent } from "vue";
-import styles from './index.module.less'
+import { defineComponent, ref } from "vue";
+import styles from "./index.module.less";
+import iconBack from "../icons/icon-right-back.png";
+import { Icon, ImagePreview, Tab, Tabs } from "vant";
 
 export default defineComponent({
-    name: 'screenModel',
-    setup(props, ctx) {
-        return () => <div class={styles.container}>123</div>
-    },
-})
+	name: "screenModel",
+	emits: ["close"],
+	setup(props, { emit }) {
+		return () => (
+			<>
+				<img class={styles.closeBtn} src={iconBack} onClick={() => emit("close")} />
+				<div class={styles.container}>
+					<Tabs swipeable animated>
+						<Tab name="投屏" title="投屏">
+							<iframe src="https://mteaonline.dayaedu.com/#/guide" />
+						</Tab>
+						<Tab name="帮助" title="帮助">
+							<iframe src="https://mstuonline.dayaedu.com/#/KeepRepaire?mode=accompany" />
+							<div class={styles.jianyi} onClick={() => emit('close', true)}>
+								意见反馈 <Icon name="arrow" />
+							</div>
+						</Tab>
+					</Tabs>
+				</div>
+			</>
+		);
+	},
+});

+ 4 - 0
src/style.css

@@ -36,12 +36,16 @@
 }
 
 /* vant 弹窗优化 */
+:root{
+  --van-duration-base: .25s;
+}
 .van-overlay{
   transition: all 0.25s;
 }
 .van-custom{
   transition: all 0.25s;
   background: transparent;
+  overflow: initial;
 }
 .van-custom.van-scale{
   transform-origin: center -25%;

+ 3 - 4
src/utils/request.ts

@@ -45,8 +45,7 @@ request.interceptors.request.use(
 request.interceptors.response.use(
 	async (res, options) => {
 		if (res.status > 299 || res.status < 200) {
-			const msg = "服务器错误,状态码" + res.status;
-			storeData.status = 'error'
+			const msg = res.statusText + ", 状态码" + res.status;
 			showToast(msg);
 			throw new Error(msg);
 		}
@@ -61,8 +60,8 @@ request.interceptors.response.use(
 				if (browserInfo.isApp) {
 					postMessage({ api: "login" });
 				} else {
-					storeData.status = 'error'
-					showToast('登录过期')
+					storeData.status = "error";
+					showToast("登录过期");
 				}
 			}
 			throw new Error(msg);

+ 21 - 25
tsconfig.json

@@ -1,27 +1,23 @@
 {
-  "compilerOptions": {
-    "target": "ESNext",
-    "useDefineForClassFields": true,
-    "module": "ESNext",
-    "moduleResolution": "Node",
-    "strict": true,
-    "jsx": "preserve",
-    "resolveJsonModule": true,
-    "isolatedModules": true,
-    "esModuleInterop": true,
-    "lib": ["ESNext", "DOM"],
-    "skipLibCheck": true,
-    "noEmit": true,
-    "baseUrl": "./",
-    "paths": {
-      "/src/*": [
-        "src/*"
-      ],
-      "/osmd-extended/*": [
-        "osmd-extended/*"
-      ]
-    },
-  },
-  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
-  "references": [{ "path": "./tsconfig.node.json" }]
+	"compilerOptions": {
+		"target": "ESNext",
+		"useDefineForClassFields": true,
+		"module": "ESNext",
+		"moduleResolution": "Node",
+		"strict": true,
+		"jsx": "preserve",
+		"resolveJsonModule": true,
+		"isolatedModules": true,
+		"esModuleInterop": true,
+		"lib": ["ESNext", "DOM"],
+		"skipLibCheck": true,
+		"noEmit": true,
+		"baseUrl": "./",
+		"paths": {
+			"/src/*": ["src/*"],
+			"/osmd-extended/*": ["osmd-extended/*"]
+		}
+	},
+	"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "osmd-extended/*.ts"],
+	"references": [{ "path": "./tsconfig.node.json" }]
 }

+ 6 - 2
vite.config.ts

@@ -11,7 +11,9 @@ export default defineConfig({
 	base: "./",
 	resolve: {},
 	plugins: [
-		legacy(),
+		legacy({
+			targets: 'last 2 versions and not dead, > 0.3%, Firefox ESR'
+		}),
 		vue(),
 		vueJsx(),
 		createStyleImportPlugin({
@@ -36,7 +38,6 @@ export default defineConfig({
 		},
 	},
 	build: {
-		target: "esnext",
 		rollupOptions: {
 			input: {
 				index: resolve(__dirname, "index.html"),
@@ -67,5 +68,8 @@ export default defineConfig({
 			},
 		},
 	},
+	preview:{
+		port: 3010
+	}
 });
 // vite.config.js