feat: add typescript support
This commit is contained in:
parent
83d68723d9
commit
906a5728b0
@ -15,5 +15,5 @@ module.exports = {
|
|||||||
rules: {
|
rules: {
|
||||||
'vue/multi-word-component-names': 0
|
'vue/multi-word-component-names': 0
|
||||||
},
|
},
|
||||||
'ignorePatterns': ['vite.config.js', 'mobile-select.js']
|
'ignorePatterns': ['vite.config.ts', 'mobile-select.js']
|
||||||
};
|
};
|
||||||
|
|||||||
31
.gitignore
vendored
31
.gitignore
vendored
@ -1,25 +1,30 @@
|
|||||||
.DS_Store
|
# Logs
|
||||||
node_modules
|
logs
|
||||||
/dist
|
*.log
|
||||||
|
|
||||||
|
|
||||||
# local env files
|
|
||||||
.env.local
|
|
||||||
.env.*.local
|
|
||||||
|
|
||||||
# Log files
|
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
pnpm-debug.log*
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
coverage
|
||||||
|
*.local
|
||||||
|
|
||||||
|
/cypress/videos/
|
||||||
|
/cypress/screenshots/
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
.idea
|
.idea
|
||||||
.vscode
|
|
||||||
*.suo
|
*.suo
|
||||||
*.ntvs*
|
*.ntvs*
|
||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
/php_backend
|
|
||||||
report.html
|
*.tsbuildinfo
|
||||||
|
|||||||
18
env.d.ts
vendored
Normal file
18
env.d.ts
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/// <reference types="vite/client" />
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Navigator {
|
||||||
|
control: any
|
||||||
|
webkitGetUserMedia: any
|
||||||
|
mozGetUserMedia: any
|
||||||
|
getUserMedia: any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.vue' {
|
||||||
|
import type { DefineComponent } from 'vue'
|
||||||
|
const component: DefineComponent<{}, {}, any>
|
||||||
|
export default component
|
||||||
|
}
|
||||||
|
|
||||||
|
export {}
|
||||||
20
index.html
20
index.html
@ -14,15 +14,15 @@
|
|||||||
<!-- integrity="sha512-KkkY/3auRhaXDFzFMpwtZ+BrS8EBQ+GfiBxdJ9jGMi6Gg74/sYbq/IZpY593pkNjTmbeRfBwjpZo+7gcpH45Ww=="-->
|
<!-- integrity="sha512-KkkY/3auRhaXDFzFMpwtZ+BrS8EBQ+GfiBxdJ9jGMi6Gg74/sYbq/IZpY593pkNjTmbeRfBwjpZo+7gcpH45Ww=="-->
|
||||||
<!-- src="https://lib.baomitu.com/eruda/3.0.1/eruda.min.js"></script>-->
|
<!-- src="https://lib.baomitu.com/eruda/3.0.1/eruda.min.js"></script>-->
|
||||||
<!-- <script>eruda.init();</script>-->
|
<!-- <script>eruda.init();</script>-->
|
||||||
<!-- <script>-->
|
<!-- <script>-->
|
||||||
<!-- var _hmt = _hmt || []-->
|
<!-- var _hmt = _hmt || []-->
|
||||||
<!-- ;(function () {-->
|
<!-- ;(function () {-->
|
||||||
<!-- var hm = document.createElement('script')-->
|
<!-- var hm = document.createElement('script')-->
|
||||||
<!-- hm.src = 'https://hm.baidu.com/hm.js?6f910830f5a7d8b5f7e75d8d67458a7a'-->
|
<!-- hm.src = 'https://hm.baidu.com/hm.js?6f910830f5a7d8b5f7e75d8d67458a7a'-->
|
||||||
<!-- var s = document.getElementsByTagName('script')[0]-->
|
<!-- var s = document.getElementsByTagName('script')[0]-->
|
||||||
<!-- s.parentNode.insertBefore(hm, s)-->
|
<!-- s.parentNode.insertBefore(hm, s)-->
|
||||||
<!-- })()-->
|
<!-- })()-->
|
||||||
<!-- </script>-->
|
<!-- </script>-->
|
||||||
<style>
|
<style>
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
display: none; /* Chrome Safari */
|
display: none; /* Chrome Safari */
|
||||||
@ -58,6 +58,6 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<script type="module" src="/src/main.js"></script>
|
<script type="module" src="/src/main.ts"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
22
package.json
22
package.json
@ -1,12 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "my-vue-app",
|
"name": "douyin-vue",
|
||||||
"version": "0.0.0",
|
"version": "1.1.0",
|
||||||
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --host",
|
"dev": "vite --host",
|
||||||
"start": "vite --host",
|
"start": "vite --host",
|
||||||
"serve": "vite --host",
|
"serve": "vite --host",
|
||||||
"build": "vite build --mode prod",
|
"build": "vite build --mode prod",
|
||||||
"build-uni-app": "vite build --mode uni",
|
"build-uni-app": "vite build --mode uni",
|
||||||
|
"build-only": "vite build",
|
||||||
|
"buildp-check": "run-p type-check \"build-only {@}\" --",
|
||||||
|
"type-check": "vue-tsc --build --force",
|
||||||
"report": "vite build",
|
"report": "vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore",
|
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore",
|
||||||
@ -16,7 +20,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jambonn/vue-lazyload": "1.0.9",
|
"@jambonn/vue-lazyload": "1.0.9",
|
||||||
"axios": "1.6.0",
|
"axios": "^1.6.8",
|
||||||
"axios-mock-adapter": "^1.22.0",
|
"axios-mock-adapter": "^1.22.0",
|
||||||
"core-js": "3.21.1",
|
"core-js": "3.21.1",
|
||||||
"dayjs": "1.11.0",
|
"dayjs": "1.11.0",
|
||||||
@ -34,13 +38,16 @@
|
|||||||
"@commitlint/cli": "^19.2.1",
|
"@commitlint/cli": "^19.2.1",
|
||||||
"@commitlint/config-conventional": "^19.1.0",
|
"@commitlint/config-conventional": "^19.1.0",
|
||||||
"@iconify/vue": "^4.1.1",
|
"@iconify/vue": "^4.1.1",
|
||||||
|
"@rollup/plugin-commonjs": "^25.0.7",
|
||||||
"@rushstack/eslint-patch": "^1.3.3",
|
"@rushstack/eslint-patch": "^1.3.3",
|
||||||
|
"@tsconfig/node20": "^20.1.2",
|
||||||
"@types/jquery": "3.5.29",
|
"@types/jquery": "3.5.29",
|
||||||
"@types/lodash-es": "^4.17.9",
|
"@types/node": "^20.11.28",
|
||||||
"@vitejs/plugin-vue": "4.0.0",
|
"@vitejs/plugin-vue": "4.0.0",
|
||||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||||
"@vue/eslint-config-prettier": "^8.0.0",
|
"@vue/eslint-config-prettier": "^8.0.0",
|
||||||
"@vue/eslint-config-typescript": "^12.0.0",
|
"@vue/eslint-config-typescript": "^12.0.0",
|
||||||
|
"@vue/tsconfig": "^0.5.1",
|
||||||
"commitizen": "^4.3.0",
|
"commitizen": "^4.3.0",
|
||||||
"cz-conventional-changelog": "^3.3.0",
|
"cz-conventional-changelog": "^3.3.0",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
@ -50,9 +57,12 @@
|
|||||||
"lint-staged": "^15.2.2",
|
"lint-staged": "^15.2.2",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"rollup-plugin-visualizer": "^5.9.2",
|
"rollup-plugin-visualizer": "^5.9.2",
|
||||||
|
"typescript": "~5.4.0",
|
||||||
"unplugin-vue-define-options": "^1.4.1",
|
"unplugin-vue-define-options": "^1.4.1",
|
||||||
"vite": "4.5.3",
|
"vite": "^5.1.6",
|
||||||
"vite-plugin-cdn-import": "0.3.5"
|
"vite-plugin-cdn-import": "0.3.5",
|
||||||
|
"vite-plugin-commonjs": "^0.10.1",
|
||||||
|
"vue-tsc": "^2.0.6"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.{js,ts,vue,jsx,tsx}": [
|
"*.{js,ts,vue,jsx,tsx}": [
|
||||||
|
|||||||
849
pnpm-lock.yaml
849
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
129
src/App.vue
129
src/App.vue
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<router-view v-slot="{ Component }">
|
<router-view v-slot="{ Component }">
|
||||||
<transition :name="transitionName">
|
<transition :name="transitionName">
|
||||||
<keep-alive :exclude="excludeRoutes">
|
<keep-alive :exclude="store.excludeRoutes">
|
||||||
<component :is="Component" />
|
<component :is="Component" />
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</transition>
|
</transition>
|
||||||
@ -17,93 +17,66 @@
|
|||||||
</div>
|
</div>
|
||||||
<Call />
|
<Call />
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
/*
|
/*
|
||||||
* try {navigator.control.gesture(false);} catch (e) {} //UC浏览器关闭默认手势事件
|
* try {navigator.control.gesture(false);} catch (e) {} //UC浏览器关闭默认手势事件
|
||||||
try {navigator.control.longpressMenu(false);} catch (e) {} //关闭长按弹出菜单
|
try {navigator.control.longpressMenu(false);} catch (e) {} //关闭长按弹出菜单
|
||||||
* */
|
* */
|
||||||
import { mapActions, mapState } from 'pinia'
|
|
||||||
import routes from './router/routes'
|
import routes from './router/routes'
|
||||||
import Call from './components/Call'
|
import Call from './components/Call.vue'
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia.js'
|
||||||
import { onMounted, ref } from 'vue'
|
import { onMounted, ref, watch } from 'vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import type { RouteRecordRaw } from 'vue-router'
|
||||||
|
|
||||||
export default {
|
const store = useBaseStore()
|
||||||
name: 'App',
|
const route = useRoute()
|
||||||
setup() {
|
const isMobile = ref(/Mobi|Android|iPhone/i.test(navigator.userAgent))
|
||||||
const isMobile = ref(/Mobi|Android|iPhone/i.test(navigator.userAgent))
|
const transitionName = ref('go')
|
||||||
onMounted(() => {
|
|
||||||
console.log('asdf', isMobile.value)
|
|
||||||
})
|
|
||||||
return { isMobile }
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
Call
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
transitionName: 'go'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState(useBaseStore, ['excludeRoutes'])
|
|
||||||
},
|
|
||||||
// watch $route 决定使用哪种过渡
|
|
||||||
watch: {
|
|
||||||
$route(to, from) {
|
|
||||||
this.setMaskDialog({ state: false, mode: this.maskDialogMode })
|
|
||||||
|
|
||||||
//footer下面的5个按钮,对跳不要用动画
|
// watch $route 决定使用哪种过渡
|
||||||
let noAnimation = [
|
watch(
|
||||||
'/',
|
() => route.path,
|
||||||
'/home',
|
(to, from) => {
|
||||||
'/slide',
|
store.setMaskDialog({ state: false, mode: store.maskDialogMode })
|
||||||
'/me',
|
//footer下面的5个按钮,对跳不要用动画
|
||||||
'/shop',
|
let noAnimation = [
|
||||||
'/message',
|
'/',
|
||||||
'/publish',
|
'/home',
|
||||||
'/home/live',
|
'/slide',
|
||||||
'slide',
|
'/me',
|
||||||
'/test'
|
'/shop',
|
||||||
]
|
'/message',
|
||||||
if (noAnimation.indexOf(from.path) !== -1 && noAnimation.indexOf(to.path) !== -1) {
|
'/publish',
|
||||||
return (this.transitionName = '')
|
'/home/live',
|
||||||
}
|
'slide',
|
||||||
|
'/test'
|
||||||
const toDepth = routes.findIndex((v) => v.path === to.path)
|
]
|
||||||
const fromDepth = routes.findIndex((v) => v.path === from.path)
|
if (noAnimation.indexOf(from) !== -1 && noAnimation.indexOf(to) !== -1) {
|
||||||
this.transitionName = toDepth > fromDepth ? 'go' : 'back'
|
return (transitionName.value = '')
|
||||||
}
|
}
|
||||||
},
|
const toDepth = routes.findIndex((v: RouteRecordRaw) => v.path === to)
|
||||||
methods: {
|
const fromDepth = routes.findIndex((v: RouteRecordRaw) => v.path === from)
|
||||||
...mapActions(useBaseStore, ['init', 'setMaskDialog']),
|
transitionName.value = toDepth > fromDepth ? 'go' : 'back'
|
||||||
setVh() {
|
|
||||||
let vh = window.innerHeight * 0.01
|
|
||||||
document.documentElement.style.setProperty('--vh', `${vh}px`)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.init()
|
|
||||||
this.setVh()
|
|
||||||
// 监听resize事件 视图大小发生变化就重新计算1vh的值
|
|
||||||
window.addEventListener('resize', () => {
|
|
||||||
location.reload()
|
|
||||||
this.setVh()
|
|
||||||
})
|
|
||||||
|
|
||||||
try {
|
|
||||||
navigator.control.gesture(false)
|
|
||||||
} catch (e) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
navigator.control.longpressMenu(false)
|
|
||||||
} catch (e) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
document.onselectstart = new Function('return false') //禁止选中文字
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
function setVh() {
|
||||||
|
let vh = window.innerHeight * 0.01
|
||||||
|
document.documentElement.style.setProperty('--vh', `${vh}px`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
store.init()
|
||||||
|
setVh()
|
||||||
|
// 监听resize事件 视图大小发生变化就重新计算1vh的值
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
location.reload()
|
||||||
|
setVh()
|
||||||
|
})
|
||||||
|
//禁止选中文字
|
||||||
|
document.onselectstart = new Function('return false') as any
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
export default {
|
export default {
|
||||||
name: 'AutoInput',
|
name: 'AutoInput',
|
||||||
props: {
|
props: {
|
||||||
|
|||||||
@ -1,54 +1,59 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="BaseHeader" :class="[isFixed ? 'fixed' : '']">
|
<div id="BaseHeader" :class="[props.isFixed ? 'fixed' : '']">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<dy-back :mode="backMode" :img="backImg" @click="back()" class="left" direction="left" />
|
<dy-back
|
||||||
|
:mode="props.backMode"
|
||||||
|
:img="props.backImg"
|
||||||
|
@click="back"
|
||||||
|
class="left"
|
||||||
|
direction="left"
|
||||||
|
/>
|
||||||
<slot name="center"><span></span></slot>
|
<slot name="center"><span></span></slot>
|
||||||
<slot name="right"><span></span></slot>
|
<slot name="right"><span></span></slot>
|
||||||
</div>
|
</div>
|
||||||
<slot name="bottom"></slot>
|
<slot name="bottom"></slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
export default {
|
import { useAttrs } from 'vue'
|
||||||
name: 'BaseHeader',
|
import { useRouter } from 'vue-router'
|
||||||
components: {},
|
|
||||||
props: {
|
defineOptions({
|
||||||
backMode: {
|
name: 'BaseHeader'
|
||||||
type: String,
|
})
|
||||||
default: 'gray'
|
|
||||||
},
|
const props = defineProps({
|
||||||
backImg: {
|
backMode: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'back'
|
default: 'gray'
|
||||||
},
|
|
||||||
isClose: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
isFixed: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data() {
|
backImg: {
|
||||||
return {}
|
type: String,
|
||||||
|
default: 'back'
|
||||||
},
|
},
|
||||||
created() {},
|
isClose: {
|
||||||
computed: {},
|
type: Boolean,
|
||||||
methods: {
|
default: false
|
||||||
back() {
|
},
|
||||||
if (this.$attrs.onBack) {
|
isFixed: {
|
||||||
this.$attrs.onBack()
|
type: Boolean,
|
||||||
} else {
|
default: true
|
||||||
this.$back()
|
}
|
||||||
}
|
})
|
||||||
}
|
const router = useRouter()
|
||||||
|
const attrs: any = useAttrs()
|
||||||
|
|
||||||
|
function back() {
|
||||||
|
if (attrs.onBack) {
|
||||||
|
attrs.onBack()
|
||||||
|
} else {
|
||||||
|
router.back()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
@import '../assets/less/index';
|
@import '@/assets/less/index';
|
||||||
|
|
||||||
#BaseHeader {
|
#BaseHeader {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
<template v-slot:header>
|
<template v-slot:header>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<dy-back mode="dark" img="close" direction="right" style="opacity: 0" />
|
<dy-back mode="dark" img="close" direction="right" style="opacity: 0" />
|
||||||
<div class="num">{{ formatNumber(comments.length) }}条评论</div>
|
<div class="num">{{ _formatNumber(comments.length) }}条评论</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<Icon icon="prime:arrow-up-right-and-arrow-down-left-from-center" @click.stop="$no" />
|
<Icon icon="prime:arrow-up-right-and-arrow-down-left-from-center" @click.stop="$no" />
|
||||||
<Icon icon="ic:round-close" @click.stop="cancel" />
|
<Icon icon="ic:round-close" @click.stop="cancel" />
|
||||||
@ -36,7 +36,7 @@
|
|||||||
<div class="time-wrapper">
|
<div class="time-wrapper">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<div class="time">
|
<div class="time">
|
||||||
{{ $time(item.create_time)
|
{{ _time(item.create_time)
|
||||||
}}{{ item.ip_location && ` · ${item.ip_location}` }}
|
}}{{ item.ip_location && ` · ${item.ip_location}` }}
|
||||||
</div>
|
</div>
|
||||||
<div class="reply-text">回复</div>
|
<div class="reply-text">回复</div>
|
||||||
@ -84,7 +84,7 @@
|
|||||||
<div class="time-wrapper">
|
<div class="time-wrapper">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<div class="time">
|
<div class="time">
|
||||||
{{ $time(child.create_time)
|
{{ _time(child.create_time)
|
||||||
}}{{ child.ip_location && ` · ${item.ip_location}` }}
|
}}{{ child.ip_location && ` · ${item.ip_location}` }}
|
||||||
</div>
|
</div>
|
||||||
<div class="reply-text">回复</div>
|
<div class="reply-text">回复</div>
|
||||||
@ -104,7 +104,7 @@
|
|||||||
v-show="!child.user_digged"
|
v-show="!child.user_digged"
|
||||||
class="love-image"
|
class="love-image"
|
||||||
/>
|
/>
|
||||||
<span>{{ formatNumber(child.digg_count) }}</span>
|
<span>{{ _formatNumber(child.digg_count) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -139,7 +139,7 @@
|
|||||||
<img
|
<img
|
||||||
:style="item.select ? 'opacity: .5;' : ''"
|
:style="item.select ? 'opacity: .5;' : ''"
|
||||||
class="avatar"
|
class="avatar"
|
||||||
:src="$imgPreview(item.avatar)"
|
:src="_checkImgUrl(item.avatar)"
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
<span>{{ item.name }}</span>
|
<span>{{ item.name }}</span>
|
||||||
@ -170,14 +170,22 @@
|
|||||||
</from-bottom-dialog>
|
</from-bottom-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import AutoInput from './AutoInput'
|
import AutoInput from './AutoInput.vue'
|
||||||
import ConfirmDialog from './dialog/ConfirmDialog'
|
import ConfirmDialog from './dialog/ConfirmDialog.vue'
|
||||||
import { mapState } from 'pinia'
|
import { mapState } from 'pinia'
|
||||||
import FromBottomDialog from './dialog/FromBottomDialog'
|
import FromBottomDialog from './dialog/FromBottomDialog.vue'
|
||||||
import Loading from './Loading'
|
import Loading from './Loading.vue'
|
||||||
import Search from './Search'
|
import Search from './Search.vue'
|
||||||
import { $no, _checkImgUrl, _formatNumber, sampleSize } from '@/utils'
|
import {
|
||||||
|
$no,
|
||||||
|
_checkImgUrl,
|
||||||
|
_formatNumber,
|
||||||
|
_showSelectDialog,
|
||||||
|
_sleep,
|
||||||
|
_time,
|
||||||
|
sampleSize
|
||||||
|
} from '@/utils'
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia'
|
||||||
import { videoComments } from '@/api/videos'
|
import { videoComments } from '@/api/videos'
|
||||||
|
|
||||||
@ -243,13 +251,14 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {},
|
mounted() {},
|
||||||
methods: {
|
methods: {
|
||||||
|
_time,
|
||||||
_formatNumber,
|
_formatNumber,
|
||||||
_checkImgUrl,
|
_checkImgUrl,
|
||||||
$no,
|
$no,
|
||||||
async handShowChildren(item) {
|
async handShowChildren(item) {
|
||||||
this.loadChildrenItemCId = item.comment_id
|
this.loadChildrenItemCId = item.comment_id
|
||||||
this.loadChildren = true
|
this.loadChildren = true
|
||||||
await this.$sleep(500)
|
await _sleep(500)
|
||||||
this.loadChildren = false
|
this.loadChildren = false
|
||||||
if (item.showChildren) {
|
if (item.showChildren) {
|
||||||
item.children = item.children.concat(sampleSize(this.comments, 10))
|
item.children = item.children.concat(sampleSize(this.comments, 10))
|
||||||
@ -273,7 +282,7 @@ export default {
|
|||||||
this.isCall = false
|
this.isCall = false
|
||||||
},
|
},
|
||||||
async getData() {
|
async getData() {
|
||||||
let res = await videoComments({ id: this.videoId })
|
let res: any = await videoComments({ id: this.videoId })
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
res.data.map((v) => {
|
res.data.map((v) => {
|
||||||
v.showChildren = false
|
v.showChildren = false
|
||||||
@ -304,19 +313,12 @@ export default {
|
|||||||
row.user_digged = !row.user_digged
|
row.user_digged = !row.user_digged
|
||||||
},
|
},
|
||||||
showOptions(row) {
|
showOptions(row) {
|
||||||
this.$showSelectDialog(this.options, (e) => {
|
_showSelectDialog(this.options, (e) => {
|
||||||
if (e.id === 1) {
|
if (e.id === 1) {
|
||||||
this.selectRow = row
|
this.selectRow = row
|
||||||
this.showPrivateChat = true
|
this.showPrivateChat = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
|
||||||
// showComment() {
|
|
||||||
// this.isCommenting = !this.isCommenting;
|
|
||||||
// console.log(666)
|
|
||||||
// }
|
|
||||||
call() {
|
|
||||||
console.log(this.commit)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<div id="UserPanel" @scroll="scroll" ref="page">
|
<div id="UserPanel" @scroll="scroll" ref="page">
|
||||||
<div ref="float" class="float" :class="state.floatFixed ? 'fixed' : ''">
|
<div ref="float" class="float" :class="state.floatFixed ? 'fixed' : ''">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<Icon @click="$emit('back')" class="icon" icon="eva:arrow-ios-back-fill" />
|
<Icon @click="emit('back')" class="icon" icon="eva:arrow-ios-back-fill" />
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<div class="float-user" v-if="state.floatFixed">
|
<div class="float-user" v-if="state.floatFixed">
|
||||||
<img
|
<img
|
||||||
@ -33,7 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
<Icon class="icon" icon="ion:search" @click.stop="$no()" />
|
<Icon class="icon" icon="ion:search" @click.stop="$no()" />
|
||||||
<Icon class="icon" icon="ri:more-line" @click.stop="$emit('showFollowSetting')" />
|
<Icon class="icon" icon="ri:more-line" @click.stop="emit('showFollowSetting')" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@ -163,7 +163,7 @@
|
|||||||
<span>关注</span>
|
<span>关注</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="followed">
|
<div class="followed">
|
||||||
<div class="l-button" @click="$emit('showFollowSetting2')">
|
<div class="l-button" @click="emit('showFollowSetting2')">
|
||||||
<span>已关注</span>
|
<span>已关注</span>
|
||||||
<Icon icon="bxs:down-arrow" class="arrow" />
|
<Icon icon="bxs:down-arrow" class="arrow" />
|
||||||
</div>
|
</div>
|
||||||
@ -232,11 +232,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import { reactive, ref, watch } from 'vue'
|
import { reactive, ref, watch } from 'vue'
|
||||||
import Utils, { $no, _checkImgUrl, _getUserDouyinId } from '@/utils'
|
import Utils, { $no, _checkImgUrl, _getUserDouyinId } from '@/utils'
|
||||||
import { useNav } from '@/utils/hooks/useNav'
|
import { useNav } from '@/utils/hooks/useNav'
|
||||||
import Posters from '@/components/Posters'
|
import Posters from '@/components/Posters.vue'
|
||||||
import { DefaultUser } from '@/utils/const_var'
|
import { DefaultUser } from '@/utils/const_var'
|
||||||
import Loading from '@/components/Loading.vue'
|
import Loading from '@/components/Loading.vue'
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia'
|
||||||
@ -244,7 +244,13 @@ import { userVideoList } from '@/api/user'
|
|||||||
|
|
||||||
const $nav = useNav()
|
const $nav = useNav()
|
||||||
const baseStore = useBaseStore()
|
const baseStore = useBaseStore()
|
||||||
const emit = defineEmits(['update:currentItem', 'back'])
|
const emit = defineEmits<{
|
||||||
|
'update:currentItem': [val: any]
|
||||||
|
back: []
|
||||||
|
showFollowSetting: []
|
||||||
|
showFollowSetting2: []
|
||||||
|
}>()
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
currentItem: {
|
currentItem: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@ -272,9 +278,7 @@ const state = reactive({
|
|||||||
previewImg: '',
|
previewImg: '',
|
||||||
floatFixed: false,
|
floatFixed: false,
|
||||||
showFollowSetting: false,
|
showFollowSetting: false,
|
||||||
|
|
||||||
floatHeight: 52,
|
floatHeight: 52,
|
||||||
|
|
||||||
loadings: {
|
loadings: {
|
||||||
showRecommend: false
|
showRecommend: false
|
||||||
},
|
},
|
||||||
@ -296,7 +300,7 @@ watch(
|
|||||||
if (newVal && !props.currentItem.aweme_list.length) {
|
if (newVal && !props.currentItem.aweme_list.length) {
|
||||||
// console.log('props.currentItem',props.currentItem)
|
// console.log('props.currentItem',props.currentItem)
|
||||||
let id = _getUserDouyinId(props.currentItem)
|
let id = _getUserDouyinId(props.currentItem)
|
||||||
let r = await userVideoList({ id })
|
let r: any = await userVideoList({ id })
|
||||||
if (r.success) {
|
if (r.success) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
r.data = r.data.map((a) => {
|
r.data = r.data.map((a) => {
|
||||||
@ -326,6 +330,10 @@ function stop(e) {
|
|||||||
|
|
||||||
function followButton() {}
|
function followButton() {}
|
||||||
|
|
||||||
|
function cancelFollow() {}
|
||||||
|
|
||||||
|
defineExpose({ cancelFollow })
|
||||||
|
|
||||||
function scroll() {
|
function scroll() {
|
||||||
// console.log('scroll', page.value.scrollTop)
|
// console.log('scroll', page.value.scrollTop)
|
||||||
let scrollTop = page.value.scrollTop
|
let scrollTop = page.value.scrollTop
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script lang="ts">
|
||||||
/*TODO 单独使用时,没有mark*/
|
/*TODO 单独使用时,没有mark*/
|
||||||
export default {
|
export default {
|
||||||
name: 'ConfirmDialog',
|
name: 'ConfirmDialog',
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import { onMounted, onUnmounted, reactive, ref, watch } from 'vue'
|
import { onMounted, onUnmounted, reactive, ref, watch } from 'vue'
|
||||||
import GM from '../../utils'
|
import GM from '../../utils'
|
||||||
import {
|
import {
|
||||||
@ -73,20 +73,30 @@ onUnmounted(() => {
|
|||||||
ob.disconnect()
|
ob.disconnect()
|
||||||
})
|
})
|
||||||
|
|
||||||
function touchStart(e) {
|
function touchStart(e: TouchEvent) {
|
||||||
slideTouchStart(e, wrapperEl.value, state)
|
slideTouchStart(e, wrapperEl.value, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
function touchMove(e) {
|
function touchMove(e: TouchEvent) {
|
||||||
slideTouchMove(e, wrapperEl.value, state, judgeValue, canNext, null, SlideType.HORIZONTAL)
|
slideTouchMove(
|
||||||
|
e,
|
||||||
|
wrapperEl.value,
|
||||||
|
state,
|
||||||
|
judgeValue,
|
||||||
|
canNext,
|
||||||
|
null,
|
||||||
|
SlideType.HORIZONTAL,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function touchEnd(e) {
|
function touchEnd(e: TouchEvent) {
|
||||||
slideTouchEnd(e, state, canNext, () => {})
|
slideTouchEnd(e, state, canNext, () => {})
|
||||||
slideReset(wrapperEl.value, state, SlideType.HORIZONTAL, emit)
|
slideReset(wrapperEl.value, state, SlideType.HORIZONTAL, emit)
|
||||||
}
|
}
|
||||||
|
|
||||||
function canNext(isNext) {
|
function canNext(isNext: boolean) {
|
||||||
return !(
|
return !(
|
||||||
(state.localIndex === 0 && !isNext) ||
|
(state.localIndex === 0 && !isNext) ||
|
||||||
(state.localIndex === state.wrapper.childrenLength - 1 && isNext)
|
(state.localIndex === state.wrapper.childrenLength - 1 && isNext)
|
||||||
@ -95,7 +105,7 @@ function canNext(isNext) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="slide hhhh">
|
<div class="slide horizontal">
|
||||||
<div
|
<div
|
||||||
class="slide-list"
|
class="slide-list"
|
||||||
ref="wrapperEl"
|
ref="wrapperEl"
|
||||||
|
|||||||
@ -4,8 +4,8 @@ export default {
|
|||||||
filePreview: 'http://192.168.0.103/static/uploads/'
|
filePreview: 'http://192.168.0.103/static/uploads/'
|
||||||
}
|
}
|
||||||
const BASE_URL_MAP = {
|
const BASE_URL_MAP = {
|
||||||
DEV: './',
|
DEV: '',
|
||||||
PROD: './',
|
PROD: '',
|
||||||
UNI: 'https://dy.ttentau.top'
|
UNI: 'https://dy.ttentau.top'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,21 +1,17 @@
|
|||||||
import * as Vue from 'vue'
|
import { createApp } from 'vue'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import mitt from 'mitt'
|
import mitt from 'mitt'
|
||||||
import './assets/less/index.less'
|
import './assets/less/index.less'
|
||||||
import { startMock } from './mock'
|
import { startMock } from '@/mock'
|
||||||
import router from './router'
|
import router from './router'
|
||||||
import mixin from './utils/mixin'
|
import mixin from './utils/mixin'
|
||||||
import VueLazyload from '@jambonn/vue-lazyload'
|
import VueLazyload from '@jambonn/vue-lazyload'
|
||||||
import { createPinia } from 'pinia'
|
import { createPinia } from 'pinia'
|
||||||
|
|
||||||
const pinia = createPinia()
|
const pinia = createPinia()
|
||||||
|
|
||||||
// const vConsole = new VConsole();
|
|
||||||
const emitter = mitt()
|
const emitter = mitt()
|
||||||
|
const app = createApp(App)
|
||||||
const app = Vue.createApp(App)
|
|
||||||
app.config.globalProperties.emitter = emitter
|
app.config.globalProperties.emitter = emitter
|
||||||
app.config.unwrapInjectedRef = true
|
|
||||||
app.provide('mitt', emitter)
|
app.provide('mitt', emitter)
|
||||||
app.mixin(mixin)
|
app.mixin(mixin)
|
||||||
const loadImage = new URL('./assets/img/icon/img-loading.png', import.meta.url).href
|
const loadImage = new URL('./assets/img/icon/img-loading.png', import.meta.url).href
|
||||||
@ -24,8 +20,8 @@ app.use(VueLazyload, {
|
|||||||
loading: loadImage,
|
loading: loadImage,
|
||||||
attempt: 1
|
attempt: 1
|
||||||
})
|
})
|
||||||
app.use(router)
|
|
||||||
app.use(pinia)
|
app.use(pinia)
|
||||||
|
app.use(router)
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
|
|
||||||
//放到最后才可以使用pinia
|
//放到最后才可以使用pinia
|
||||||
@ -8,22 +8,22 @@ import MockAdapter from 'axios-mock-adapter'
|
|||||||
|
|
||||||
const mock = new MockAdapter(axiosInstance, { delayResponse: 300 })
|
const mock = new MockAdapter(axiosInstance, { delayResponse: 300 })
|
||||||
|
|
||||||
function getPage2(params) {
|
function getPage2(params: any): { limit: number; offset: number; pageNo: number } {
|
||||||
let offset = params.pageNo * params.pageSize
|
const offset = params.pageNo * params.pageSize
|
||||||
let limit = params.pageNo * params.pageSize + params.pageSize
|
const limit = params.pageNo * params.pageSize + params.pageSize
|
||||||
return { limit, offset, pageNo: params.pageNo }
|
return { limit, offset, pageNo: params.pageNo }
|
||||||
}
|
}
|
||||||
|
|
||||||
let allRecommendPosts = []
|
let allRecommendPosts = []
|
||||||
let userVideos = []
|
let userVideos = []
|
||||||
let allRecommendVideos = posts6.map((v) => {
|
let allRecommendVideos = posts6.map((v: any) => {
|
||||||
v.type = 'recommend-video'
|
v.type = 'recommend-video'
|
||||||
return v
|
return v
|
||||||
})
|
})
|
||||||
|
|
||||||
// console.log('allRecommendVideos', allRecommendVideos)
|
// console.log('allRecommendVideos', allRecommendVideos)
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line
|
||||||
let t = [
|
const t = [
|
||||||
{
|
{
|
||||||
type: 'imgs',
|
type: 'imgs',
|
||||||
src: `https://imgapi.cn/bing.php`,
|
src: `https://imgapi.cn/bing.php`,
|
||||||
@ -74,7 +74,7 @@ async function fetchData() {
|
|||||||
}
|
}
|
||||||
v = v.map((w) => {
|
v = v.map((w) => {
|
||||||
w.type = 'recommend-video'
|
w.type = 'recommend-video'
|
||||||
let item = userList.find((a) => String(a.uid) === String(w.author_user_id))
|
const item: any = userList.find((a) => String(a.uid) === String(w.author_user_id))
|
||||||
if (item) w.author = item
|
if (item) w.author = item
|
||||||
return w
|
return w
|
||||||
})
|
})
|
||||||
@ -86,7 +86,7 @@ async function fetchData() {
|
|||||||
//TODO 有个bug,一开始只返回了6条数据,但第二次前端传过来的pageNo是2了,就是会从第10条数据开始返回,导致中间漏了4条
|
//TODO 有个bug,一开始只返回了6条数据,但第二次前端传过来的pageNo是2了,就是会从第10条数据开始返回,导致中间漏了4条
|
||||||
export async function startMock() {
|
export async function startMock() {
|
||||||
mock.onGet(/video\/recommended/).reply(async (config) => {
|
mock.onGet(/video\/recommended/).reply(async (config) => {
|
||||||
let page = getPage2(config.params)
|
const page = getPage2(config.params)
|
||||||
console.log('allRecommendVideos', cloneDeep(allRecommendVideos.length), page)
|
console.log('allRecommendVideos', cloneDeep(allRecommendVideos.length), page)
|
||||||
return [
|
return [
|
||||||
200,
|
200,
|
||||||
@ -102,7 +102,7 @@ export async function startMock() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
mock.onGet(/video\/comments/).reply(async (config) => {
|
mock.onGet(/video\/comments/).reply(async (config) => {
|
||||||
let videoIds = [
|
const videoIds = [
|
||||||
'7260749400622894336',
|
'7260749400622894336',
|
||||||
'7128686458763889956',
|
'7128686458763889956',
|
||||||
'7293100687989148943',
|
'7293100687989148943',
|
||||||
@ -124,8 +124,8 @@ export async function startMock() {
|
|||||||
if (!videoIds.includes(String(id))) {
|
if (!videoIds.includes(String(id))) {
|
||||||
id = videoIds[random(0, videoIds.length - 1)]
|
id = videoIds[random(0, videoIds.length - 1)]
|
||||||
}
|
}
|
||||||
let r2 = await fetch(`${FILE_URL}/comments/video_id_${id}.json`)
|
const r2 = await fetch(`${FILE_URL}/comments/video_id_${id}.json`)
|
||||||
let v = await r2.json()
|
const v = await r2.json()
|
||||||
if (v) {
|
if (v) {
|
||||||
return [200, { data: v, code: 200 }]
|
return [200, { data: v, code: 200 }]
|
||||||
}
|
}
|
||||||
@ -133,7 +133,7 @@ export async function startMock() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
mock.onGet(/video\/private/).reply(async (config) => {
|
mock.onGet(/video\/private/).reply(async (config) => {
|
||||||
let page = getPage2(config.params)
|
const page = getPage2(config.params)
|
||||||
return [
|
return [
|
||||||
200,
|
200,
|
||||||
{
|
{
|
||||||
@ -148,7 +148,7 @@ export async function startMock() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
mock.onGet(/video\/like/).reply(async (config) => {
|
mock.onGet(/video\/like/).reply(async (config) => {
|
||||||
let page = getPage2(config.params)
|
const page = getPage2(config.params)
|
||||||
return [
|
return [
|
||||||
200,
|
200,
|
||||||
{
|
{
|
||||||
@ -163,18 +163,18 @@ export async function startMock() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
mock.onGet(/video\/my/).reply(async (config) => {
|
mock.onGet(/video\/my/).reply(async (config) => {
|
||||||
let page = getPage2(config.params)
|
const page = getPage2(config.params)
|
||||||
if (!userVideos.length) {
|
if (!userVideos.length) {
|
||||||
// let r = await fetch(BASE_URL + '/data/user-71158770.json')
|
// let r = await fetch(BASE_URL + '/data/user-71158770.json')
|
||||||
// let r = await fetch(BASE_URL + '/data/user-8357999.json')
|
// let r = await fetch(BASE_URL + '/data/user-8357999.json')
|
||||||
let r = await fetch(BASE_URL + '/data/user_video_list/user-12345xiaolaohu.json')
|
const r = await fetch(BASE_URL + '/data/user_video_list/user-12345xiaolaohu.json')
|
||||||
let list = await r.json()
|
const list = await r.json()
|
||||||
const baseStore = useBaseStore()
|
const baseStore = useBaseStore()
|
||||||
let userList = cloneDeep(baseStore.users)
|
const userList = cloneDeep(baseStore.users)
|
||||||
|
|
||||||
userVideos = list.map((w) => {
|
userVideos = list.map((w) => {
|
||||||
if (userList.length) {
|
if (userList.length) {
|
||||||
let item = userList.find((a) => String(a.uid) === String(w.author_user_id))
|
const item = userList.find((a) => String(a.uid) === String(w.author_user_id))
|
||||||
if (item) w.author = item
|
if (item) w.author = item
|
||||||
}
|
}
|
||||||
return w
|
return w
|
||||||
@ -196,7 +196,7 @@ export async function startMock() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
mock.onGet(/video\/history/).reply(async (config) => {
|
mock.onGet(/video\/history/).reply(async (config) => {
|
||||||
let page = getPage2(config.params)
|
const page = getPage2(config.params)
|
||||||
return [
|
return [
|
||||||
200,
|
200,
|
||||||
{
|
{
|
||||||
@ -231,9 +231,9 @@ export async function startMock() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
mock.onGet(/user\/video_list/).reply(async (config) => {
|
mock.onGet(/user\/video_list/).reply(async (config) => {
|
||||||
let id = config.params.id
|
const id = config.params.id
|
||||||
let r2 = await fetch(`${FILE_URL}/user_video_list/user-${id}.json`)
|
const r2 = await fetch(`${FILE_URL}/user_video_list/user-${id}.json`)
|
||||||
let v = await r2.json()
|
const v = await r2.json()
|
||||||
if (v) {
|
if (v) {
|
||||||
return [200, { data: v, code: 200 }]
|
return [200, { data: v, code: 200 }]
|
||||||
}
|
}
|
||||||
@ -241,11 +241,11 @@ export async function startMock() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
mock.onGet(/user\/panel/).reply(async () => {
|
mock.onGet(/user\/panel/).reply(async () => {
|
||||||
let r2 = await fetch(BASE_URL + '/data/users.json')
|
const r2 = await fetch(BASE_URL + '/data/users.json')
|
||||||
let v = await r2.json()
|
const v = await r2.json()
|
||||||
// let item = v.find(a => a.uid === '68310389333')
|
// let item = v.find(a => a.uid === '68310389333')
|
||||||
// let item = v.find(a => a.uid === '59054327754')
|
// let item = v.find(a => a.uid === '59054327754')
|
||||||
let item = v.find((a) => a.uid === '2739632844317827')
|
const item = v.find((a) => a.uid === '2739632844317827')
|
||||||
if (item) {
|
if (item) {
|
||||||
return [200, { data: item, code: 200 }]
|
return [200, { data: item, code: 200 }]
|
||||||
}
|
}
|
||||||
@ -253,13 +253,13 @@ export async function startMock() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
mock.onGet(/user\/friends/).reply(async () => {
|
mock.onGet(/user\/friends/).reply(async () => {
|
||||||
let r2 = await fetch(BASE_URL + '/data/users.json')
|
const r2 = await fetch(BASE_URL + '/data/users.json')
|
||||||
let v = await r2.json()
|
const v = await r2.json()
|
||||||
return [200, { data: v, code: 200 }]
|
return [200, { data: v, code: 200 }]
|
||||||
})
|
})
|
||||||
|
|
||||||
mock.onGet(/historyOther/).reply(async (config) => {
|
mock.onGet(/historyOther/).reply(async (config) => {
|
||||||
let page = getPage2(config.params)
|
const page = getPage2(config.params)
|
||||||
return [
|
return [
|
||||||
200,
|
200,
|
||||||
{
|
{
|
||||||
@ -275,10 +275,10 @@ export async function startMock() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
mock.onGet(/post\/recommended/).reply(async (config) => {
|
mock.onGet(/post\/recommended/).reply(async (config) => {
|
||||||
let page = getPage2(config.params)
|
const page = getPage2(config.params)
|
||||||
|
|
||||||
if (!allRecommendPosts.length) {
|
if (!allRecommendPosts.length) {
|
||||||
let r = await fetch(BASE_URL + '/data/posts.json')
|
const r = await fetch(BASE_URL + '/data/posts.json')
|
||||||
allRecommendPosts = await r.json()
|
allRecommendPosts = await r.json()
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
@ -296,10 +296,10 @@ export async function startMock() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
mock.onGet(/shop\/recommended/).reply(async (config) => {
|
mock.onGet(/shop\/recommended/).reply(async (config) => {
|
||||||
let page = getPage2(config.params)
|
const page = getPage2(config.params)
|
||||||
|
|
||||||
let r2 = await fetch(BASE_URL + '/data/goods.json')
|
const r2 = await fetch(BASE_URL + '/data/goods.json')
|
||||||
let v = await r2.json()
|
const v = await r2.json()
|
||||||
return [
|
return [
|
||||||
200,
|
200,
|
||||||
{
|
{
|
||||||
@ -1,18 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="Music">
|
<div id="Music">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<dy-back mode="light" @click="$back" />
|
<dy-back mode="light" @click="router.back()" />
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<div class="center" v-if="isFixed">
|
<div class="center" v-if="data.isFixed">
|
||||||
<span class="f16">{{ music.name }}</span>
|
<span class="f16">{{ data.music.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<!-- TODO 没有淡入淡出的特效-->
|
<!-- TODO 没有淡入淡出的特效-->
|
||||||
<template v-if="isFixed">
|
<template v-if="data.isFixed">
|
||||||
<img
|
<img
|
||||||
class="star"
|
class="star"
|
||||||
v-if="isCollect"
|
v-if="data.isCollect"
|
||||||
src="../../assets/img/icon/star-yellow.png"
|
src="../../assets/img/icon/star-yellow.png"
|
||||||
@click.stop="toggleCollect()"
|
@click.stop="toggleCollect()"
|
||||||
/>
|
/>
|
||||||
@ -23,38 +23,54 @@
|
|||||||
@click.stop="toggleCollect()"
|
@click.stop="toggleCollect()"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<div class="logo" v-if="!isFixed" @click="$nav('/home/music-rank-list')">抖音音乐榜</div>
|
<div class="logo" v-if="!data.isFixed" @click="nav('/home/music-rank-list')">
|
||||||
<img class="share" src="../../assets/img/icon/share-white.png" @click="isSharing = true" />
|
抖音音乐榜
|
||||||
|
</div>
|
||||||
|
<img
|
||||||
|
class="share"
|
||||||
|
src="../../assets/img/icon/share-white.png"
|
||||||
|
@click="data.isSharing = true"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<Scroll
|
<Scroll
|
||||||
class="Scroll"
|
class="Scroll"
|
||||||
:fixedHeight="180"
|
:fixedHeight="180"
|
||||||
@fixed="(e) => (this.isFixed = e)"
|
@fixed="(e) => (data.isFixed = e)"
|
||||||
@pulldown="loadData"
|
@pulldown="loadData"
|
||||||
>
|
>
|
||||||
<div class="desc">
|
<div class="desc">
|
||||||
<div class="cover-wrapper" @click="togglePlay()">
|
<div class="cover-wrapper" @click="togglePlay()">
|
||||||
<img class="cover" :src="$imgPreview(music.cover)" alt="" />
|
<img class="cover" :src="_checkImgUrl(data.music.cover)" alt="" />
|
||||||
<img v-if="!isPlay" src="../../assets/img/icon/play-white.png" alt="" class="play" />
|
<img
|
||||||
<img v-if="isPlay" src="../../assets/img/icon/pause-white.png" alt="" class="play" />
|
v-if="!data.isPlay"
|
||||||
|
src="../../assets/img/icon/play-white.png"
|
||||||
|
alt=""
|
||||||
|
class="play"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
v-if="data.isPlay"
|
||||||
|
src="../../assets/img/icon/pause-white.png"
|
||||||
|
alt=""
|
||||||
|
class="play"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="name">{{ music.name }}</div>
|
<div class="name">{{ data.music.name }}</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="user">{{ music.author }}</div>
|
<div class="user">{{ data.music.author }}</div>
|
||||||
<div class="peoples">{{ formatNumber(music.use_count) }} 人使用</div>
|
<div class="peoples">{{ _formatNumber(data.music.use_count) }} 人使用</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="collection" @click.stop="toggleCollect()">
|
<div class="collection" @click.stop="toggleCollect()">
|
||||||
<img v-if="isCollect" src="../../assets/img/icon/star-yellow.png" />
|
<img v-if="data.isCollect" src="../../assets/img/icon/star-yellow.png" />
|
||||||
<img v-else src="../../assets/img/icon/star-white.png" />
|
<img v-else src="../../assets/img/icon/star-white.png" />
|
||||||
<span>{{ isCollect ? '已' : '' }}收藏</span>
|
<span>{{ data.isCollect ? '已' : '' }}收藏</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Posters mode="music" :list="videos" />
|
<Posters mode="music" :list="data.videos" />
|
||||||
<Loading :is-full-screen="false" v-if="loading" />
|
<Loading :is-full-screen="false" v-if="data.loading" />
|
||||||
<NoMore v-else />
|
<NoMore v-else />
|
||||||
</Scroll>
|
</Scroll>
|
||||||
</div>
|
</div>
|
||||||
@ -70,165 +86,161 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Share
|
<Share
|
||||||
v-model="isSharing"
|
v-model="data.isSharing"
|
||||||
mode="music"
|
mode="music"
|
||||||
ref="share"
|
ref="share"
|
||||||
pageId="Music"
|
pageId="Music"
|
||||||
@showDouyinCode="showDouyinCode = true"
|
@showDouyinCode="data.showDouyinCode = true"
|
||||||
@showShare2WeChatZone="shareType = 2"
|
@showShare2WeChatZone="data.shareType = 2"
|
||||||
@share2WeChat="shareType = 3"
|
@share2WeChat="data.shareType = 3"
|
||||||
@share2QQZone="shareType = 4"
|
@share2QQZone="data.shareType = 4"
|
||||||
@share2QQ="shareType = 5"
|
@share2QQ="data.shareType = 5"
|
||||||
@share2Webo="shareType = 8"
|
@share2Webo="data.shareType = 8"
|
||||||
@ShareToFriend="delayShowDialog((e) => (this.shareToFriend = true))"
|
@ShareToFriend="delayShowDialog(() => (data.shareToFriend = true))"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<DouyinCode v-model="showDouyinCode" />
|
<DouyinCode v-model="data.showDouyinCode" />
|
||||||
|
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
v-model:visible="showSharePassword"
|
v-model:visible="data.showSharePassword"
|
||||||
title="你的口令已复制"
|
title="你的口令已复制"
|
||||||
subtitle="0F.:/ a【风就应该自由要什么归宿】长按复制此条消息,打开抖音搜索,聆听音乐##kwu3VCixHl8##[抖音口令]"
|
subtitle="0F.:/ a【风就应该自由要什么归宿】长按复制此条消息,打开抖音搜索,聆听音乐##kwu3VCixHl8##[抖音口令]"
|
||||||
:okText="okText"
|
:okText="data.okText"
|
||||||
cancelText="不分享了"
|
cancelText="不分享了"
|
||||||
@ok="shareType = -1"
|
@ok="data.shareType = -1"
|
||||||
@cancel="shareType = -1"
|
@cancel="data.shareType = -1"
|
||||||
>
|
>
|
||||||
<template v-slot:header>
|
<template v-slot:header>
|
||||||
<img style="width: 100%" src="../../assets/img/icon/share-password.webp" alt="" />
|
<img style="width: 100%" src="../../assets/img/icon/share-password.webp" alt="" />
|
||||||
</template>
|
</template>
|
||||||
</ConfirmDialog>
|
</ConfirmDialog>
|
||||||
|
|
||||||
<ShareToFriend pageId="Music" v-model="shareToFriend" />
|
<ShareToFriend pageId="Music" v-model="data.shareToFriend" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import Posters from '../../components/Posters'
|
import Posters from '../../components/Posters.vue'
|
||||||
import Scroll from '../../components/Scroll'
|
import Scroll from '../../components/Scroll.vue'
|
||||||
import Loading from '../../components/Loading'
|
import Loading from '../../components/Loading.vue'
|
||||||
import Share from '../../components/Share'
|
import Share from '../../components/Share.vue'
|
||||||
import DouyinCode from '../../components/DouyinCode'
|
import DouyinCode from '../../components/DouyinCode.vue'
|
||||||
import ConfirmDialog from '../../components/dialog/ConfirmDialog'
|
import ConfirmDialog from '../../components/dialog/ConfirmDialog.vue'
|
||||||
import ShareToFriend from './components/ShareToFriend'
|
import ShareToFriend from './components/ShareToFriend.vue'
|
||||||
import { myVideo } from '@/api/videos'
|
import { myVideo } from '@/api/videos'
|
||||||
|
import { onDeactivated, onMounted, onUnmounted, reactive, watch } from 'vue'
|
||||||
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
import { useNav } from '@/utils/hooks/useNav'
|
||||||
|
import { $no, $notice, _checkImgUrl, _formatNumber } from '@/utils'
|
||||||
|
|
||||||
export default {
|
const route = useRoute()
|
||||||
name: 'Music',
|
const router = useRouter()
|
||||||
components: {
|
const nav = useNav()
|
||||||
Scroll,
|
|
||||||
Posters,
|
|
||||||
Loading,
|
|
||||||
Share,
|
|
||||||
DouyinCode,
|
|
||||||
ConfirmDialog,
|
|
||||||
ShareToFriend
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
loading: false,
|
|
||||||
isFixed: false,
|
|
||||||
isCollect: false,
|
|
||||||
isPlay: false,
|
|
||||||
isSharing: false,
|
|
||||||
okText: '',
|
|
||||||
|
|
||||||
showSharePassword: false,
|
const data = reactive({
|
||||||
shareToFriend: false,
|
loading: false,
|
||||||
shareType: -1,
|
isFixed: false,
|
||||||
|
isCollect: false,
|
||||||
|
isPlay: false,
|
||||||
|
isSharing: false,
|
||||||
|
okText: '',
|
||||||
|
|
||||||
showDouyinCode: false,
|
showSharePassword: false,
|
||||||
audio: new Audio(),
|
shareToFriend: false,
|
||||||
total: 0,
|
shareType: -1,
|
||||||
pageNo: 0,
|
|
||||||
pageSize: 15,
|
|
||||||
videos: [],
|
|
||||||
|
|
||||||
music: {
|
showDouyinCode: false,
|
||||||
name: '发如雪',
|
audio: new Audio(),
|
||||||
mp3: 'https://m3.8js.net:99/2014/211204142150965.mp3',
|
total: 0,
|
||||||
cover: new URL('../../assets/img/music-cover/7.jpg', import.meta.url).href,
|
pageNo: 0,
|
||||||
author: '周杰伦',
|
pageSize: 15,
|
||||||
duration: 60,
|
videos: [],
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
music: {
|
||||||
is_play: false
|
name: '发如雪',
|
||||||
}
|
mp3: 'https://m3.8js.net:99/2014/211204142150965.mp3',
|
||||||
}
|
cover: new URL('../../assets/img/music-cover/7.jpg', import.meta.url).href,
|
||||||
},
|
author: '周杰伦',
|
||||||
watch: {
|
duration: 60,
|
||||||
shareType(newVal) {
|
use_count: 37441000,
|
||||||
if (newVal === -1) return
|
is_collect: false,
|
||||||
this.showSharePassword = true
|
is_play: false
|
||||||
switch (newVal) {
|
|
||||||
case 2:
|
|
||||||
case 3:
|
|
||||||
return (this.okText = '去微信粘贴')
|
|
||||||
case 4:
|
|
||||||
case 5:
|
|
||||||
return (this.okText = '去QQ粘贴')
|
|
||||||
case 8:
|
|
||||||
return (this.okText = '去微博粘贴')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
if (this.$route.query.name) {
|
|
||||||
this.music = this.$route.query
|
|
||||||
}
|
|
||||||
this.loadData(true)
|
|
||||||
},
|
|
||||||
computed: {},
|
|
||||||
methods: {
|
|
||||||
toggleCollect() {
|
|
||||||
this.isCollect = !this.isCollect
|
|
||||||
},
|
|
||||||
async loadData(init = false) {
|
|
||||||
if (this.loading) return
|
|
||||||
if (!init) {
|
|
||||||
if (this.total <= this.videos.length) {
|
|
||||||
return this.$notice('暂时没有更多了')
|
|
||||||
}
|
|
||||||
this.pageNo++
|
|
||||||
}
|
|
||||||
this.loading = true
|
|
||||||
let res = await myVideo({
|
|
||||||
pageNo: this.pageNo,
|
|
||||||
pageSize: this.pageSize
|
|
||||||
})
|
|
||||||
this.loading = false
|
|
||||||
if (res.code === this.SUCCESS) {
|
|
||||||
this.videos = this.videos.concat(res.data.list)
|
|
||||||
this.total = res.data.total
|
|
||||||
}
|
|
||||||
},
|
|
||||||
togglePlay() {
|
|
||||||
this.isPlay = !this.isPlay
|
|
||||||
if (this.isPlay) {
|
|
||||||
if (!this.audio.src) {
|
|
||||||
this.audio.src = this.music.mp3
|
|
||||||
}
|
|
||||||
this.audio.play()
|
|
||||||
this.audio.addEventListener('ended', () => (this.isPlay = false))
|
|
||||||
} else {
|
|
||||||
this.stopPlay()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
delayShowDialog(cb) {
|
|
||||||
setTimeout(() => {
|
|
||||||
cb()
|
|
||||||
}, 100)
|
|
||||||
},
|
|
||||||
stopPlay() {
|
|
||||||
this.audio.pause()
|
|
||||||
this.audio.removeEventListener('ended', null)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
unmounted() {
|
|
||||||
this.stopPlay()
|
|
||||||
},
|
|
||||||
deactivated() {
|
|
||||||
this.stopPlay()
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => data.shareType,
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal === -1) return
|
||||||
|
data.showSharePassword = true
|
||||||
|
switch (newVal) {
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
return (data.okText = '去微信粘贴')
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
return (data.okText = '去QQ粘贴')
|
||||||
|
case 8:
|
||||||
|
return (data.okText = '去微博粘贴')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (route.query.name) {
|
||||||
|
data.music = route.query as any
|
||||||
|
}
|
||||||
|
loadData(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(stopPlay)
|
||||||
|
onDeactivated(stopPlay)
|
||||||
|
|
||||||
|
function toggleCollect() {
|
||||||
|
data.isCollect = !data.isCollect
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadData(init = false) {
|
||||||
|
if (data.loading) return
|
||||||
|
if (!init) {
|
||||||
|
if (data.total <= data.videos.length) {
|
||||||
|
return $notice('暂时没有更多了')
|
||||||
|
}
|
||||||
|
data.pageNo++
|
||||||
|
}
|
||||||
|
data.loading = true
|
||||||
|
let res: any = await myVideo({
|
||||||
|
pageNo: data.pageNo,
|
||||||
|
pageSize: data.pageSize
|
||||||
|
})
|
||||||
|
data.loading = false
|
||||||
|
if (res.success) {
|
||||||
|
data.videos = data.videos.concat(res.data.list)
|
||||||
|
data.total = res.data.total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function togglePlay() {
|
||||||
|
data.isPlay = !data.isPlay
|
||||||
|
if (data.isPlay) {
|
||||||
|
if (!data.audio.src) {
|
||||||
|
data.audio.src = data.music.mp3
|
||||||
|
}
|
||||||
|
data.audio.play()
|
||||||
|
data.audio.addEventListener('ended', () => (data.isPlay = false))
|
||||||
|
} else {
|
||||||
|
stopPlay()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function delayShowDialog(cb) {
|
||||||
|
setTimeout(() => {
|
||||||
|
cb()
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopPlay() {
|
||||||
|
data.audio.pause()
|
||||||
|
data.audio.removeEventListener('ended', null)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="MusicRankList" @scroll="scroll">
|
<div class="MusicRankList" @scroll="scroll">
|
||||||
<dy-back mode="light" img="back" @click="$back()" class="fixed-back" direction="left" />
|
<dy-back mode="light" img="back" @click="router.back()" class="fixed-back" direction="left" />
|
||||||
<div class="fixed-header" :style="fixedStyle">
|
<div class="fixed-header" :style="fixedStyle">
|
||||||
<span class="f16">抖音音乐榜</span>
|
<span class="f16">抖音音乐榜</span>
|
||||||
</div>
|
</div>
|
||||||
@ -8,23 +8,23 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="l-header">
|
<div class="l-header">
|
||||||
<img src="../../assets/img/icon/music-rank-list.webp" alt="" />
|
<img src="../../assets/img/icon/music-rank-list.webp" alt="" />
|
||||||
<div class="update-time">更新于:{{ $dateFormat(updateTime, 'D') }}</div>
|
<div class="update-time">更新于:{{ _dateFormat(data.updateTime, 'D') }}</div>
|
||||||
</div>
|
</div>
|
||||||
<Indicator
|
<Indicator
|
||||||
name="musicRankList"
|
name="musicRankList"
|
||||||
tabStyleWidth="33%"
|
tabStyleWidth="33%"
|
||||||
:tabTexts="['热歌榜', '飙升樘', '原创榜']"
|
:tabTexts="['热歌榜', '飙升樘', '原创榜']"
|
||||||
v-model:active-index="contentIndex"
|
v-model:active-index="data.contentIndex"
|
||||||
>
|
>
|
||||||
</Indicator>
|
</Indicator>
|
||||||
<SlideHorizontal name="musicRankList" v-model:index="contentIndex">
|
<SlideHorizontal name="musicRankList" v-model:index="data.contentIndex">
|
||||||
<SlideItem>
|
<SlideItem>
|
||||||
<div class="list">
|
<div class="list">
|
||||||
<div
|
<div
|
||||||
class="item"
|
class="item"
|
||||||
:key="index"
|
:key="index"
|
||||||
v-for="(item, index) in hotList"
|
v-for="(item, index) in data.hotList"
|
||||||
@click="togglePlay(item, hotList)"
|
@click="togglePlay(item, data.hotList)"
|
||||||
>
|
>
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<div class="rank-wrapper">
|
<div class="rank-wrapper">
|
||||||
@ -51,7 +51,7 @@
|
|||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="music">
|
<div class="music">
|
||||||
<div class="cover-wrapper">
|
<div class="cover-wrapper">
|
||||||
<img v-lazy="$imgPreview(item.cover)" alt="" class="cover" />
|
<img v-lazy="_checkImgUrl(item.cover)" alt="" class="cover" />
|
||||||
<img
|
<img
|
||||||
v-if="!item.is_play"
|
v-if="!item.is_play"
|
||||||
src="../../assets/img/icon/play-white.png"
|
src="../../assets/img/icon/play-white.png"
|
||||||
@ -70,9 +70,9 @@
|
|||||||
<div class="author">{{ item.author }}</div>
|
<div class="author">{{ item.author }}</div>
|
||||||
<div class="desc-bottom">
|
<div class="desc-bottom">
|
||||||
<div class="duration">
|
<div class="duration">
|
||||||
{{ $duration(item.duration) }}
|
{{ _duration(item.duration) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="use_count">{{ formatNumber(item.use_count) }}人使用</div>
|
<div class="use_count">{{ _formatNumber(item.use_count) }}人使用</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -92,7 +92,7 @@
|
|||||||
<img
|
<img
|
||||||
src="../../assets/img/icon/menu2-white.png"
|
src="../../assets/img/icon/menu2-white.png"
|
||||||
alt=""
|
alt=""
|
||||||
@click.stop="$nav('/home/music')"
|
@click.stop="nav('/home/music')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -116,8 +116,8 @@
|
|||||||
<div
|
<div
|
||||||
class="item"
|
class="item"
|
||||||
:key="index"
|
:key="index"
|
||||||
v-for="(item, index) in hotList"
|
v-for="(item, index) in data.hotList"
|
||||||
@click="togglePlay(item, hotList)"
|
@click="togglePlay(item, data.hotList)"
|
||||||
>
|
>
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<div class="rank-wrapper">
|
<div class="rank-wrapper">
|
||||||
@ -144,7 +144,7 @@
|
|||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="music">
|
<div class="music">
|
||||||
<div class="cover-wrapper">
|
<div class="cover-wrapper">
|
||||||
<img v-lazy="$imgPreview(item.cover)" alt="" class="cover" />
|
<img v-lazy="_checkImgUrl(item.cover)" alt="" class="cover" />
|
||||||
<img
|
<img
|
||||||
v-if="!item.is_play"
|
v-if="!item.is_play"
|
||||||
src="../../assets/img/icon/play-white.png"
|
src="../../assets/img/icon/play-white.png"
|
||||||
@ -163,9 +163,9 @@
|
|||||||
<div class="author">{{ item.author }}</div>
|
<div class="author">{{ item.author }}</div>
|
||||||
<div class="desc-bottom">
|
<div class="desc-bottom">
|
||||||
<div class="duration">
|
<div class="duration">
|
||||||
{{ $duration(item.duration) }}
|
{{ _duration(item.duration) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="use_count">{{ formatNumber(item.use_count) }}人使用</div>
|
<div class="use_count">{{ _formatNumber(item.use_count) }}人使用</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -185,7 +185,7 @@
|
|||||||
<img
|
<img
|
||||||
src="../../assets/img/icon/menu2-white.png"
|
src="../../assets/img/icon/menu2-white.png"
|
||||||
alt=""
|
alt=""
|
||||||
@click.stop="$nav('/home/music')"
|
@click.stop="nav('/home/music')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -209,8 +209,8 @@
|
|||||||
<div
|
<div
|
||||||
class="item"
|
class="item"
|
||||||
:key="index"
|
:key="index"
|
||||||
v-for="(item, index) in hotList"
|
v-for="(item, index) in data.hotList"
|
||||||
@click="togglePlay(item, hotList)"
|
@click="togglePlay(item, data.hotList)"
|
||||||
>
|
>
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<div class="rank-wrapper">
|
<div class="rank-wrapper">
|
||||||
@ -237,7 +237,7 @@
|
|||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="music">
|
<div class="music">
|
||||||
<div class="cover-wrapper">
|
<div class="cover-wrapper">
|
||||||
<img v-lazy="$imgPreview(item.cover)" alt="" class="cover" />
|
<img v-lazy="_checkImgUrl(item.cover)" alt="" class="cover" />
|
||||||
<img
|
<img
|
||||||
v-if="!item.is_play"
|
v-if="!item.is_play"
|
||||||
src="../../assets/img/icon/play-white.png"
|
src="../../assets/img/icon/play-white.png"
|
||||||
@ -256,9 +256,9 @@
|
|||||||
<div class="author">{{ item.author }}</div>
|
<div class="author">{{ item.author }}</div>
|
||||||
<div class="desc-bottom">
|
<div class="desc-bottom">
|
||||||
<div class="duration">
|
<div class="duration">
|
||||||
{{ $duration(item.duration) }}
|
{{ _duration(item.duration) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="use_count">{{ formatNumber(item.use_count) }}人使用</div>
|
<div class="use_count">{{ _formatNumber(item.use_count) }}人使用</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -278,7 +278,7 @@
|
|||||||
<img
|
<img
|
||||||
src="../../assets/img/icon/menu2-white.png"
|
src="../../assets/img/icon/menu2-white.png"
|
||||||
alt=""
|
alt=""
|
||||||
@click.stop="$nav('/home/music')"
|
@click.stop="nav('/home/music')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -301,255 +301,258 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
|
||||||
export default {
|
<script setup lang="ts">
|
||||||
name: 'MusicRankList',
|
import { useRouter } from 'vue-router'
|
||||||
components: {},
|
import { computed, onDeactivated, onMounted, onUnmounted, reactive } from 'vue'
|
||||||
data() {
|
import { $notice, _checkImgUrl, _dateFormat, _duration, _formatNumber } from '@/utils/index.jsx'
|
||||||
return {
|
import { useNav } from '@/utils/hooks/useNav'
|
||||||
contentIndex: 0,
|
|
||||||
hotList: [
|
defineOptions({
|
||||||
{
|
name: 'MusicRankList'
|
||||||
name: '龙卷风',
|
})
|
||||||
mp3: 'http://im5.tongbu.com/rings/singerring/zt_uunGo_1/5605.mp3',
|
const router = useRouter()
|
||||||
cover: new URL('../../assets/img/music-cover/1.jpg', import.meta.url).href,
|
const nav = useNav()
|
||||||
author: '周杰伦',
|
const data = reactive({
|
||||||
duration: 99,
|
contentIndex: 0,
|
||||||
use_count: 37441000,
|
hotList: [
|
||||||
is_collect: false,
|
{
|
||||||
is_play: false
|
name: '龙卷风',
|
||||||
},
|
mp3: 'http://im5.tongbu.com/rings/singerring/zt_uunGo_1/5605.mp3',
|
||||||
{
|
cover: new URL('../../assets/img/music-cover/1.jpg', import.meta.url).href,
|
||||||
name: '爱在西元前',
|
author: '周杰伦',
|
||||||
mp3: 'https://m3.8js.net:99/1916/501204165042405.mp3',
|
duration: 99,
|
||||||
cover: new URL('../../assets/img/music-cover/2.jpg', import.meta.url).href,
|
use_count: 37441000,
|
||||||
author: '周杰伦',
|
is_collect: false,
|
||||||
duration: 60,
|
is_play: false
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '蜗牛',
|
|
||||||
mp3: 'http://im5.tongbu.com/rings/singerring/zt_uunGo_1/3684.mp3',
|
|
||||||
cover: new URL('../../assets/img/music-cover/3.jpg', import.meta.url).href,
|
|
||||||
author: '周杰伦',
|
|
||||||
duration: 60,
|
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '半岛铁盒',
|
|
||||||
mp3: 'https://m3.8js.net:99/2016n/46/94745.mp3',
|
|
||||||
cover: new URL('../../assets/img/music-cover/4.jpg', import.meta.url).href,
|
|
||||||
author: '周杰伦',
|
|
||||||
duration: 60,
|
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '轨迹',
|
|
||||||
mp3: 'https://m3.8js.net:99/1832/411204324135934.mp3',
|
|
||||||
cover: new URL('../../assets/img/music-cover/5.jpg', import.meta.url).href,
|
|
||||||
author: '周杰伦',
|
|
||||||
duration: 60,
|
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '七里香',
|
|
||||||
mp3: 'https://m3.8js.net:99/2016n/14/53717.mp3',
|
|
||||||
cover: new URL('../../assets/img/music-cover/6.jpg', import.meta.url).href,
|
|
||||||
author: '周杰伦',
|
|
||||||
duration: 60,
|
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '发如雪',
|
|
||||||
mp3: 'https://m3.8js.net:99/2014/211204142150965.mp3',
|
|
||||||
cover: new URL('../../assets/img/music-cover/7.jpg', import.meta.url).href,
|
|
||||||
author: '周杰伦',
|
|
||||||
duration: 60,
|
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '霍元甲',
|
|
||||||
mp3: 'https://m3.8js.net:99/1921/261204212643140.mp3',
|
|
||||||
cover: new URL('../../assets/img/music-cover/8.jpg', import.meta.url).href,
|
|
||||||
author: '周杰伦',
|
|
||||||
duration: 60,
|
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '千里之外(周杰伦/费玉清)',
|
|
||||||
mp3: 'http://im5.tongbu.com/rings/singerring/zt_uunGo_1/121.mp3',
|
|
||||||
cover: new URL('../../assets/img/music-cover/9.jpg', import.meta.url).href,
|
|
||||||
author: '周杰伦',
|
|
||||||
duration: 60,
|
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '菊花台',
|
|
||||||
mp3: 'http://im5.tongbu.com/rings/singerring/zt_uunGo_1/2022.mp3',
|
|
||||||
cover: new URL('../../assets/img/music-cover/10.jpg', import.meta.url).href,
|
|
||||||
author: '周杰伦',
|
|
||||||
duration: 60,
|
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '不能说的秘密',
|
|
||||||
mp3: 'http://im5.tongbu.com/rings/singerring/zt_uunGo_1/165.mp3',
|
|
||||||
cover: new URL('../../assets/img/music-cover/11.jpg', import.meta.url).href,
|
|
||||||
author: '周杰伦',
|
|
||||||
duration: 60,
|
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '牛仔很忙',
|
|
||||||
mp3: 'http://im5.tongbu.com/rings/singerring/zt_uunGo_1/219.mp3',
|
|
||||||
cover: new URL('../../assets/img/music-cover/12.jpg', import.meta.url).href,
|
|
||||||
author: '周杰伦',
|
|
||||||
duration: 60,
|
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '给我一首歌的时间',
|
|
||||||
mp3: 'https://m3.8js.net:99/1938/041204380445445.mp3',
|
|
||||||
cover: new URL('../../assets/img/music-cover/13.jpg', import.meta.url).href,
|
|
||||||
author: '周杰伦',
|
|
||||||
duration: 60,
|
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '烟花易冷',
|
|
||||||
mp3: 'https://m3.8js.net:99/1828/051204280535192.mp3',
|
|
||||||
cover: new URL('../../assets/img/music-cover/14.jpg', import.meta.url).href,
|
|
||||||
author: '周杰伦',
|
|
||||||
duration: 60,
|
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '惊叹号',
|
|
||||||
mp3: 'https://m3.8js.net:99/20111103/150.mp3',
|
|
||||||
cover: new URL('../../assets/img/music-cover/15.jpg', import.meta.url).href,
|
|
||||||
author: '周杰伦',
|
|
||||||
duration: 60,
|
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '明明就',
|
|
||||||
mp3: 'https://m3.8js.net:99/2016n/27/96537.mp3',
|
|
||||||
cover: new URL('../../assets/img/music-cover/16.jpg', import.meta.url).href,
|
|
||||||
author: '周杰伦',
|
|
||||||
duration: 60,
|
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '算什么男人',
|
|
||||||
mp3: 'https://m3.8js.net:99/20150107/429.mp3',
|
|
||||||
cover: new URL('../../assets/img/music-cover/17.jpg', import.meta.url).href,
|
|
||||||
author: '周杰伦',
|
|
||||||
duration: 60,
|
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '告白气球',
|
|
||||||
mp3: 'https://m3.8js.net:99/20161016/481.mp3',
|
|
||||||
cover: new URL('../../assets/img/music-cover/18.jpg', import.meta.url).href,
|
|
||||||
author: '周杰伦',
|
|
||||||
duration: 60,
|
|
||||||
use_count: 37441000,
|
|
||||||
is_collect: false,
|
|
||||||
is_play: false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
updateTime: Date.now(),
|
|
||||||
audio: new Audio(),
|
|
||||||
scrollTop: -1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
fixedStyle() {
|
|
||||||
return {
|
|
||||||
opacity: this.scrollTop / 120 > 1 ? 1 : this.scrollTop / 120
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.hotList = this.hotList.concat(this.hotList).concat(this.hotList).concat(this.hotList)
|
|
||||||
this.hotList = this.hotList.slice(0, 50)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
scroll(e) {
|
|
||||||
this.scrollTop = e.target.scrollTop
|
|
||||||
},
|
},
|
||||||
toggleCollect(item) {
|
{
|
||||||
item.is_collect = !item.is_collect
|
name: '爱在西元前',
|
||||||
if (item.is_collect) {
|
mp3: 'https://m3.8js.net:99/1916/501204165042405.mp3',
|
||||||
this.$notice('收藏成功')
|
cover: new URL('../../assets/img/music-cover/2.jpg', import.meta.url).href,
|
||||||
} else {
|
author: '周杰伦',
|
||||||
this.$notice('取消收藏')
|
duration: 60,
|
||||||
}
|
use_count: 37441000,
|
||||||
|
is_collect: false,
|
||||||
|
is_play: false
|
||||||
},
|
},
|
||||||
togglePlay(item, list) {
|
{
|
||||||
list.map((v) => {
|
name: '蜗牛',
|
||||||
if (v.name !== item.name) {
|
mp3: 'http://im5.tongbu.com/rings/singerring/zt_uunGo_1/3684.mp3',
|
||||||
v.is_play = false
|
cover: new URL('../../assets/img/music-cover/3.jpg', import.meta.url).href,
|
||||||
}
|
author: '周杰伦',
|
||||||
})
|
duration: 60,
|
||||||
item.is_play = !item.is_play
|
use_count: 37441000,
|
||||||
if (item.is_play) {
|
is_collect: false,
|
||||||
this.audio.pause()
|
is_play: false
|
||||||
this.audio.src = item.mp3
|
|
||||||
this.audio.currentTime = 0
|
|
||||||
this.audio.play()
|
|
||||||
this.audio.addEventListener('ended', () => (item.is_play = false))
|
|
||||||
} else {
|
|
||||||
this.stopPlay()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
stopPlay() {
|
{
|
||||||
this.audio.pause()
|
name: '半岛铁盒',
|
||||||
this.audio.currentTime = 0
|
mp3: 'https://m3.8js.net:99/2016n/46/94745.mp3',
|
||||||
this.audio.removeEventListener('ended', null)
|
cover: new URL('../../assets/img/music-cover/4.jpg', import.meta.url).href,
|
||||||
|
author: '周杰伦',
|
||||||
|
duration: 60,
|
||||||
|
use_count: 37441000,
|
||||||
|
is_collect: false,
|
||||||
|
is_play: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '轨迹',
|
||||||
|
mp3: 'https://m3.8js.net:99/1832/411204324135934.mp3',
|
||||||
|
cover: new URL('../../assets/img/music-cover/5.jpg', import.meta.url).href,
|
||||||
|
author: '周杰伦',
|
||||||
|
duration: 60,
|
||||||
|
use_count: 37441000,
|
||||||
|
is_collect: false,
|
||||||
|
is_play: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '七里香',
|
||||||
|
mp3: 'https://m3.8js.net:99/2016n/14/53717.mp3',
|
||||||
|
cover: new URL('../../assets/img/music-cover/6.jpg', import.meta.url).href,
|
||||||
|
author: '周杰伦',
|
||||||
|
duration: 60,
|
||||||
|
use_count: 37441000,
|
||||||
|
is_collect: false,
|
||||||
|
is_play: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '发如雪',
|
||||||
|
mp3: 'https://m3.8js.net:99/2014/211204142150965.mp3',
|
||||||
|
cover: new URL('../../assets/img/music-cover/7.jpg', import.meta.url).href,
|
||||||
|
author: '周杰伦',
|
||||||
|
duration: 60,
|
||||||
|
use_count: 37441000,
|
||||||
|
is_collect: false,
|
||||||
|
is_play: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '霍元甲',
|
||||||
|
mp3: 'https://m3.8js.net:99/1921/261204212643140.mp3',
|
||||||
|
cover: new URL('../../assets/img/music-cover/8.jpg', import.meta.url).href,
|
||||||
|
author: '周杰伦',
|
||||||
|
duration: 60,
|
||||||
|
use_count: 37441000,
|
||||||
|
is_collect: false,
|
||||||
|
is_play: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '千里之外(周杰伦/费玉清)',
|
||||||
|
mp3: 'http://im5.tongbu.com/rings/singerring/zt_uunGo_1/121.mp3',
|
||||||
|
cover: new URL('../../assets/img/music-cover/9.jpg', import.meta.url).href,
|
||||||
|
author: '周杰伦',
|
||||||
|
duration: 60,
|
||||||
|
use_count: 37441000,
|
||||||
|
is_collect: false,
|
||||||
|
is_play: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '菊花台',
|
||||||
|
mp3: 'http://im5.tongbu.com/rings/singerring/zt_uunGo_1/2022.mp3',
|
||||||
|
cover: new URL('../../assets/img/music-cover/10.jpg', import.meta.url).href,
|
||||||
|
author: '周杰伦',
|
||||||
|
duration: 60,
|
||||||
|
use_count: 37441000,
|
||||||
|
is_collect: false,
|
||||||
|
is_play: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '不能说的秘密',
|
||||||
|
mp3: 'http://im5.tongbu.com/rings/singerring/zt_uunGo_1/165.mp3',
|
||||||
|
cover: new URL('../../assets/img/music-cover/11.jpg', import.meta.url).href,
|
||||||
|
author: '周杰伦',
|
||||||
|
duration: 60,
|
||||||
|
use_count: 37441000,
|
||||||
|
is_collect: false,
|
||||||
|
is_play: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '牛仔很忙',
|
||||||
|
mp3: 'http://im5.tongbu.com/rings/singerring/zt_uunGo_1/219.mp3',
|
||||||
|
cover: new URL('../../assets/img/music-cover/12.jpg', import.meta.url).href,
|
||||||
|
author: '周杰伦',
|
||||||
|
duration: 60,
|
||||||
|
use_count: 37441000,
|
||||||
|
is_collect: false,
|
||||||
|
is_play: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '给我一首歌的时间',
|
||||||
|
mp3: 'https://m3.8js.net:99/1938/041204380445445.mp3',
|
||||||
|
cover: new URL('../../assets/img/music-cover/13.jpg', import.meta.url).href,
|
||||||
|
author: '周杰伦',
|
||||||
|
duration: 60,
|
||||||
|
use_count: 37441000,
|
||||||
|
is_collect: false,
|
||||||
|
is_play: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '烟花易冷',
|
||||||
|
mp3: 'https://m3.8js.net:99/1828/051204280535192.mp3',
|
||||||
|
cover: new URL('../../assets/img/music-cover/14.jpg', import.meta.url).href,
|
||||||
|
author: '周杰伦',
|
||||||
|
duration: 60,
|
||||||
|
use_count: 37441000,
|
||||||
|
is_collect: false,
|
||||||
|
is_play: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '惊叹号',
|
||||||
|
mp3: 'https://m3.8js.net:99/20111103/150.mp3',
|
||||||
|
cover: new URL('../../assets/img/music-cover/15.jpg', import.meta.url).href,
|
||||||
|
author: '周杰伦',
|
||||||
|
duration: 60,
|
||||||
|
use_count: 37441000,
|
||||||
|
is_collect: false,
|
||||||
|
is_play: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '明明就',
|
||||||
|
mp3: 'https://m3.8js.net:99/2016n/27/96537.mp3',
|
||||||
|
cover: new URL('../../assets/img/music-cover/16.jpg', import.meta.url).href,
|
||||||
|
author: '周杰伦',
|
||||||
|
duration: 60,
|
||||||
|
use_count: 37441000,
|
||||||
|
is_collect: false,
|
||||||
|
is_play: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '算什么男人',
|
||||||
|
mp3: 'https://m3.8js.net:99/20150107/429.mp3',
|
||||||
|
cover: new URL('../../assets/img/music-cover/17.jpg', import.meta.url).href,
|
||||||
|
author: '周杰伦',
|
||||||
|
duration: 60,
|
||||||
|
use_count: 37441000,
|
||||||
|
is_collect: false,
|
||||||
|
is_play: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '告白气球',
|
||||||
|
mp3: 'https://m3.8js.net:99/20161016/481.mp3',
|
||||||
|
cover: new URL('../../assets/img/music-cover/18.jpg', import.meta.url).href,
|
||||||
|
author: '周杰伦',
|
||||||
|
duration: 60,
|
||||||
|
use_count: 37441000,
|
||||||
|
is_collect: false,
|
||||||
|
is_play: false
|
||||||
}
|
}
|
||||||
},
|
],
|
||||||
unmounted() {
|
updateTime: Date.now(),
|
||||||
this.stopPlay()
|
audio: new Audio(),
|
||||||
},
|
scrollTop: -1
|
||||||
deactivated() {
|
})
|
||||||
this.stopPlay()
|
|
||||||
|
const fixedStyle = computed(() => {
|
||||||
|
return {
|
||||||
|
opacity: data.scrollTop / 120 > 1 ? 1 : data.scrollTop / 120
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
data.hotList = data.hotList.concat(data.hotList).concat(data.hotList).concat(data.hotList)
|
||||||
|
data.hotList = data.hotList.slice(0, 50)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(stopPlay)
|
||||||
|
onDeactivated(stopPlay)
|
||||||
|
|
||||||
|
function scroll(e) {
|
||||||
|
data.scrollTop = e.target.scrollTop
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleCollect(item) {
|
||||||
|
item.is_collect = !item.is_collect
|
||||||
|
if (item.is_collect) {
|
||||||
|
$notice('收藏成功')
|
||||||
|
} else {
|
||||||
|
$notice('取消收藏')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
|
||||||
|
|
||||||
|
function togglePlay(item, list) {
|
||||||
|
list.map((v) => {
|
||||||
|
if (v.name !== item.name) {
|
||||||
|
v.is_play = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
item.is_play = !item.is_play
|
||||||
|
if (item.is_play) {
|
||||||
|
data.audio.pause()
|
||||||
|
data.audio.src = item.mp3
|
||||||
|
data.audio.currentTime = 0
|
||||||
|
data.audio.play()
|
||||||
|
data.audio.addEventListener('ended', () => (item.is_play = false))
|
||||||
|
} else {
|
||||||
|
data.stopPlay()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopPlay() {
|
||||||
|
data.audio.pause()
|
||||||
|
data.audio.currentTime = 0
|
||||||
|
data.audio.removeEventListener('ended', null)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
@import '../../assets/less/index';
|
@import '../../assets/less/index';
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="Publish">
|
<div class="Publish">
|
||||||
<video id="video" autoplay="autoplay" style="width: 100%; height: calc(100% - 60rem)"></video>
|
<video id="video" autoplay style="width: 100%; height: calc(100% - 60rem)"></video>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<SlideHorizontal style="height: 60rem" v-model:index="activeIndex">
|
<SlideHorizontal style="height: 60rem" v-model:index="activeIndex">
|
||||||
<SlideItem style="width: 20vw"></SlideItem>
|
<SlideItem style="width: 20vw"></SlideItem>
|
||||||
@ -20,7 +20,7 @@
|
|||||||
</SlideHorizontal>
|
</SlideHorizontal>
|
||||||
</div>
|
</div>
|
||||||
<div class="float">
|
<div class="float">
|
||||||
<Icon class="close" icon="mingcute:close-line" @click="$back" />
|
<Icon class="close" icon="mingcute:close-line" @click="router.back()" />
|
||||||
<div class="choose-music">
|
<div class="choose-music">
|
||||||
<Icon icon="vaadin:music" />
|
<Icon icon="vaadin:music" />
|
||||||
<span>选择音乐</span>
|
<span>选择音乐</span>
|
||||||
@ -48,9 +48,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import { mapState } from 'pinia'
|
import { onMounted, ref } from 'vue'
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'Publish'
|
||||||
|
})
|
||||||
|
const router = useRouter()
|
||||||
|
const videoEl = ref(null)
|
||||||
|
const activeIndex = ref(1)
|
||||||
|
|
||||||
//访问用户媒体设备的兼容方法
|
//访问用户媒体设备的兼容方法
|
||||||
function getUserMedia(constrains, success, error) {
|
function getUserMedia(constrains, success, error) {
|
||||||
@ -63,51 +70,37 @@ function getUserMedia(constrains, success, error) {
|
|||||||
} else if (navigator.mozGetUserMedia) {
|
} else if (navigator.mozGetUserMedia) {
|
||||||
//Firefox浏览器
|
//Firefox浏览器
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
navagator.mozGetUserMedia(constrains).then(success).catch(error)
|
navigator.mozGetUserMedia(constrains).then(success).catch(error)
|
||||||
} else if (navigator.getUserMedia) {
|
} else if (navigator.getUserMedia) {
|
||||||
//旧版API
|
//旧版API
|
||||||
navigator.getUserMedia(constrains).then(success).catch(error)
|
navigator.getUserMedia(constrains).then(success).catch(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
function getMedia() {
|
||||||
name: 'Publish',
|
// let constraints = {video: {width: this.bodyWidth, height: this.bodyHeight - 60}, audio: false};
|
||||||
data() {
|
// let constraints = {video:{width:480,height:320}, audio: false};
|
||||||
return {
|
let constraints = { video: true, audio: false }
|
||||||
video: null,
|
try {
|
||||||
activeIndex: 1
|
getUserMedia(
|
||||||
}
|
constraints,
|
||||||
},
|
(MediaStream) => {
|
||||||
computed: {
|
videoEl.value.srcObject = MediaStream
|
||||||
...mapState(useBaseStore, ['bodyHeight', 'bodyWidth'])
|
videoEl.value.play()
|
||||||
},
|
},
|
||||||
mounted() {
|
function (PermissionDeniedError) {
|
||||||
//获得video摄像头区域
|
console.log(PermissionDeniedError)
|
||||||
this.video = document.getElementById('video')
|
|
||||||
this.getMedia()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getMedia() {
|
|
||||||
// let constraints = {video: {width: this.bodyWidth, height: this.bodyHeight - 60}, audio: false};
|
|
||||||
// let constraints = {video:{width:480,height:320}, audio: false};
|
|
||||||
let constraints = { video: true, audio: false }
|
|
||||||
try {
|
|
||||||
getUserMedia(
|
|
||||||
constraints,
|
|
||||||
(MediaStream) => {
|
|
||||||
this.video.srcObject = MediaStream
|
|
||||||
this.video.play()
|
|
||||||
},
|
|
||||||
function (PermissionDeniedError) {
|
|
||||||
console.log(PermissionDeniedError)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} catch (e) {
|
|
||||||
console.log('e', e)
|
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
|
} catch (e) {
|
||||||
|
console.log('e', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
videoEl.value = document.getElementById('video')
|
||||||
|
getMedia()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
|||||||
@ -160,7 +160,7 @@
|
|||||||
:videoId="state.recommendList[state.itemIndex]?.id"
|
:videoId="state.recommendList[state.itemIndex]?.id"
|
||||||
:canDownload="state.recommendList[state.itemIndex]?.canDownload"
|
:canDownload="state.recommendList[state.itemIndex]?.canDownload"
|
||||||
@play-feedback="state.showPlayFeedback = true"
|
@play-feedback="state.showPlayFeedback = true"
|
||||||
@shareToFriend="delayShowDialog((e) => (state.shareToFriend = true))"
|
@shareToFriend="delayShowDialog(() => (state.shareToFriend = true))"
|
||||||
@showDouyinCode="state.showDouyinCode = true"
|
@showDouyinCode="state.showDouyinCode = true"
|
||||||
@download="state.shareType = 9"
|
@download="state.shareType = 9"
|
||||||
/>
|
/>
|
||||||
@ -185,7 +185,7 @@
|
|||||||
|
|
||||||
<FollowSetting2
|
<FollowSetting2
|
||||||
v-model:currentItem="state.currentItem"
|
v-model:currentItem="state.currentItem"
|
||||||
@cancelFollow="$refs.uploader.cancelFollow()"
|
@cancelFollow="uploader.cancelFollow()"
|
||||||
v-model="state.showFollowSetting2"
|
v-model="state.showFollowSetting2"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -199,13 +199,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="jsx">
|
<script setup lang="tsx">
|
||||||
import SlideHorizontal from '@/components/slide/SlideHorizontal.vue'
|
import SlideHorizontal from '@/components/slide/SlideHorizontal.vue'
|
||||||
import SlideItem from '@/components/slide/SlideItem.vue'
|
import SlideItem from '@/components/slide/SlideItem.vue'
|
||||||
import Comment from '../../components/Comment.vue'
|
import Comment from '../../components/Comment.vue'
|
||||||
import Share from '../../components/Share.vue'
|
import Share from '../../components/Share.vue'
|
||||||
import IndicatorHome from './components/IndicatorHome.vue'
|
import IndicatorHome from './components/IndicatorHome.vue'
|
||||||
import { onActivated, onDeactivated, onMounted, onUnmounted, reactive } from 'vue'
|
import { onActivated, onDeactivated, onMounted, onUnmounted, reactive, ref } from 'vue'
|
||||||
import bus, { EVENT_KEY } from '../../utils/bus'
|
import bus, { EVENT_KEY } from '../../utils/bus'
|
||||||
import { useNav } from '@/utils/hooks/useNav'
|
import { useNav } from '@/utils/hooks/useNav'
|
||||||
import PlayFeedback from '@/pages/home/components/PlayFeedback.vue'
|
import PlayFeedback from '@/pages/home/components/PlayFeedback.vue'
|
||||||
@ -229,11 +229,13 @@ import { useBaseStore } from '@/store/pinia'
|
|||||||
|
|
||||||
const nav = useNav()
|
const nav = useNav()
|
||||||
const baseStore = useBaseStore()
|
const baseStore = useBaseStore()
|
||||||
|
const uploader = ref()
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
active: true,
|
active: true,
|
||||||
baseIndex: 1,
|
baseIndex: 1,
|
||||||
navIndex: 4,
|
navIndex: 4,
|
||||||
|
itemIndex: 0,
|
||||||
test: '',
|
test: '',
|
||||||
recommendList: [],
|
recommendList: [],
|
||||||
isSharing: false,
|
isSharing: false,
|
||||||
@ -253,13 +255,14 @@ const state = reactive({
|
|||||||
commentVisible: false,
|
commentVisible: false,
|
||||||
fullScreen: false,
|
fullScreen: false,
|
||||||
currentItem: {
|
currentItem: {
|
||||||
|
aweme_id: '',
|
||||||
author: DefaultUser,
|
author: DefaultUser,
|
||||||
isRequest: false,
|
isRequest: false,
|
||||||
aweme_list: []
|
aweme_list: []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function delayShowDialog(cb) {
|
function delayShowDialog(cb: Function) {
|
||||||
setTimeout(cb, 400)
|
setTimeout(cb, 400)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,14 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="MyCard">
|
<div id="MyCard">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<dy-back mode="light" @click="$back" />
|
<dy-back mode="light" @click="router.back" />
|
||||||
<!-- todo 差一-->
|
<!-- todo 差一-->
|
||||||
<img class="share" src="../../assets/img/icon/share-white.png" @click="isSharing = true" />
|
<img
|
||||||
|
class="share"
|
||||||
|
src="../../assets/img/icon/share-white.png"
|
||||||
|
@click="data.isSharing = true"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="qrcode">
|
<div class="qrcode">
|
||||||
<img class="qrcode-bg" src="../../assets/img/icon/me/code-bg.png" alt="" />
|
<img class="qrcode-bg" src="../../assets/img/icon/me/code-bg.png" alt="" />
|
||||||
<img class="avatar" :src="_checkImgUrl(userinfo.cover_url[0].url_list[0])" alt="" />
|
<img class="avatar" :src="_checkImgUrl(store.userinfo.cover_url[0].url_list[0])" alt="" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="name">ZZZZZZZZZZ</span>
|
<span class="name">ZZZZZZZZZZ</span>
|
||||||
@ -30,65 +34,52 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Share v-model="isSharing" mode="qrcode" ref="share" page-id="MyCard" />
|
<Share v-model:value="data.isSharing" mode="qrcode" ref="share" page-id="MyCard" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
|
||||||
import Share from '../../components/Share'
|
<script setup lang="ts">
|
||||||
import { mapState } from 'pinia'
|
import Share from '../../components/Share.vue'
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia'
|
||||||
import { _checkImgUrl } from '@/utils'
|
import { $no, _checkImgUrl } from '@/utils'
|
||||||
|
import { reactive, watch } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
export default {
|
defineOptions({
|
||||||
name: 'MyCard',
|
name: 'MyCard'
|
||||||
components: {
|
})
|
||||||
Share
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
const router = useRouter()
|
||||||
return {
|
const store = useBaseStore()
|
||||||
isSharing: false,
|
const data = reactive({
|
||||||
okText: '',
|
isSharing: false,
|
||||||
|
okText: '',
|
||||||
|
showSharePassword: false,
|
||||||
|
shareToFriend: false,
|
||||||
|
shareType: -1,
|
||||||
|
showDouyinCode: false
|
||||||
|
})
|
||||||
|
|
||||||
showSharePassword: false,
|
watch(
|
||||||
shareToFriend: false,
|
() => data.shareType,
|
||||||
shareType: -1,
|
(newVal) => {
|
||||||
|
if (newVal === -1) return
|
||||||
showDouyinCode: false
|
data.showSharePassword = true
|
||||||
}
|
switch (newVal) {
|
||||||
},
|
case 2:
|
||||||
watch: {
|
case 3:
|
||||||
shareType(newVal) {
|
return (data.okText = '去微信粘贴')
|
||||||
if (newVal === -1) return
|
case 4:
|
||||||
this.showSharePassword = true
|
case 5:
|
||||||
switch (newVal) {
|
return (data.okText = '去QQ粘贴')
|
||||||
case 2:
|
case 8:
|
||||||
case 3:
|
return (data.okText = '去微博粘贴')
|
||||||
return (this.okText = '去微信粘贴')
|
|
||||||
case 4:
|
|
||||||
case 5:
|
|
||||||
return (this.okText = '去QQ粘贴')
|
|
||||||
case 8:
|
|
||||||
return (this.okText = '去微博粘贴')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {},
|
|
||||||
computed: {
|
|
||||||
...mapState(useBaseStore, ['userinfo'])
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
_checkImgUrl,
|
|
||||||
delayShowDialog(cb) {
|
|
||||||
setTimeout(() => {
|
|
||||||
cb()
|
|
||||||
}, 100)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style lang="less" scoped>
|
||||||
@import '../../assets/less/index';
|
@import '../../assets/less/index';
|
||||||
|
|
||||||
#MyCard {
|
#MyCard {
|
||||||
|
|||||||
@ -9,13 +9,13 @@
|
|||||||
<div class="list">
|
<div class="list">
|
||||||
<div
|
<div
|
||||||
class="item"
|
class="item"
|
||||||
v-for="(item, index) in list"
|
v-for="(item, index) in data.list"
|
||||||
:key="index"
|
:key="index"
|
||||||
@click="togglePlay(item, list)"
|
@click="togglePlay(item, data.list)"
|
||||||
>
|
>
|
||||||
<div class="music">
|
<div class="music">
|
||||||
<div class="cover-wrapper">
|
<div class="cover-wrapper">
|
||||||
<img v-lazy="$imgPreview(item.cover)" alt="" class="cover" />
|
<img v-lazy="_checkImgUrl(item.cover)" alt="" class="cover" />
|
||||||
<img
|
<img
|
||||||
v-if="!item.is_play"
|
v-if="!item.is_play"
|
||||||
src="@/assets/img/icon/play-white.png"
|
src="@/assets/img/icon/play-white.png"
|
||||||
@ -33,7 +33,7 @@
|
|||||||
<span class="name">{{ item.name }}</span>
|
<span class="name">{{ item.name }}</span>
|
||||||
<div class="author">{{ item.author }}</div>
|
<div class="author">{{ item.author }}</div>
|
||||||
<div class="desc-bottom">
|
<div class="desc-bottom">
|
||||||
<div class="duration">{{ $duration(item.duration) }}</div>
|
<div class="duration">{{ _duration(item.duration) }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -41,126 +41,124 @@
|
|||||||
<img
|
<img
|
||||||
src="@/assets/img/icon/menu2-white.png"
|
src="@/assets/img/icon/menu2-white.png"
|
||||||
alt=""
|
alt=""
|
||||||
@click.stop="$nav('/home/music', item)"
|
@click.stop="nav('/home/music', item)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Loading v-if="loading" :is-full-screen="false" />
|
<Loading v-if="data.loading" :is-full-screen="false" />
|
||||||
<no-more v-else class="mb7r" />
|
<no-more v-else class="mb7r" />
|
||||||
</div>
|
</div>
|
||||||
<div class="float-play-music" v-if="currentItem">
|
<div class="float-play-music" v-if="data.currentItem">
|
||||||
<div class="process" :style="{ width: process + 'px' }"></div>
|
<div class="process" :style="{ width: data.process + 'px' }"></div>
|
||||||
<div class="music-wrapper">
|
<div class="music-wrapper">
|
||||||
<div class="music">
|
<div class="music">
|
||||||
<div class="cover-wrapper" @click="togglePlay(currentItem, list)">
|
<div class="cover-wrapper" @click="togglePlay(data.currentItem, data.list)">
|
||||||
<img v-lazy="$imgPreview(currentItem.cover)" alt="" class="cover" />
|
<img v-lazy="_checkImgUrl(data.currentItem.cover)" alt="" class="cover" />
|
||||||
<img
|
<img
|
||||||
v-if="!currentItem.is_play"
|
v-if="!data.currentItem.is_play"
|
||||||
src="@/assets/img/icon/play-white.png"
|
src="@/assets/img/icon/play-white.png"
|
||||||
alt=""
|
alt=""
|
||||||
class="play"
|
class="play"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
v-if="currentItem.is_play"
|
v-if="data.currentItem.is_play"
|
||||||
src="@/assets/img/icon/pause-white.png"
|
src="@/assets/img/icon/pause-white.png"
|
||||||
alt=""
|
alt=""
|
||||||
class="play"
|
class="play"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="desc">
|
<div class="desc">
|
||||||
<span class="name">{{ currentItem.name }}</span>
|
<span class="name">{{ data.currentItem.name }}</span>
|
||||||
<div class="desc-bottom">
|
<div class="desc-bottom">
|
||||||
<div class="duration">{{ $duration(currentItem.duration) }}</div>
|
<div class="duration">{{ _duration(data.currentItem.duration) }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="option">
|
<div class="option">
|
||||||
<dy-button type="primary" size="small" @click="$no">使用</dy-button>
|
<dy-button type="primary" size="small" @click="_no">使用</dy-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import { mapState } from 'pinia'
|
|
||||||
import { userCollect } from '@/api/user'
|
import { userCollect } from '@/api/user'
|
||||||
import { useBaseStore } from '@/store/pinia'
|
|
||||||
|
|
||||||
export default {
|
import { onMounted, onUnmounted, reactive } from 'vue'
|
||||||
name: 'MusicCollect',
|
import { useNav } from '@/utils/hooks/useNav.js'
|
||||||
components: {},
|
import { useBaseStore } from '@/store/pinia'
|
||||||
props: {},
|
import { _checkImgUrl, _duration, _no } from '@/utils'
|
||||||
data() {
|
|
||||||
return {
|
defineOptions({
|
||||||
loading: false,
|
name: 'MusicCollect'
|
||||||
list: [],
|
})
|
||||||
audio: new Audio(),
|
|
||||||
currentItem: null,
|
const store = useBaseStore()
|
||||||
step: null,
|
const nav = useNav()
|
||||||
process: 0
|
const data = reactive({
|
||||||
}
|
loading: false,
|
||||||
},
|
list: [],
|
||||||
computed: {
|
audio: new Audio(),
|
||||||
...mapState(useBaseStore, ['bodyWidth'])
|
currentItem: null,
|
||||||
},
|
step: null,
|
||||||
created() {
|
process: 0
|
||||||
this.getData()
|
})
|
||||||
},
|
|
||||||
mounted() {
|
onMounted(() => {
|
||||||
this.audio.addEventListener('loadedmetadata', () => {
|
getData()
|
||||||
this.currentItem.duration = this.audio.duration
|
data.audio.addEventListener('loadedmetadata', () => {
|
||||||
this.step = this.bodyWidth / Math.floor(this.audio.duration)
|
data.currentItem.duration = data.audio.duration
|
||||||
})
|
data.step = store.bodyWidth / Math.floor(data.audio.duration)
|
||||||
this.audio.addEventListener('timeupdate', (e) => {
|
})
|
||||||
this.process = Math.ceil(e.target.currentTime) * this.step
|
data.audio.addEventListener('timeupdate', (e: any) => {
|
||||||
})
|
data.process = Math.ceil(e.target.currentTime) * data.step
|
||||||
},
|
})
|
||||||
methods: {
|
})
|
||||||
async getData() {
|
|
||||||
this.loading = true
|
onUnmounted(stopPlay)
|
||||||
let res = await userCollect()
|
|
||||||
this.loading = false
|
async function getData() {
|
||||||
if (res.code === this.SUCCESS) {
|
data.loading = true
|
||||||
this.list = res.data.music.list
|
let res: any = await userCollect()
|
||||||
}
|
data.loading = false
|
||||||
},
|
if (res.success) {
|
||||||
togglePlay(item, list) {
|
data.list = res.data.music.list
|
||||||
list.map((v) => {
|
|
||||||
if (v.name !== item.name) {
|
|
||||||
v.is_play = false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
item.is_play = !item.is_play
|
|
||||||
if (item.is_play) {
|
|
||||||
if (this.currentItem) {
|
|
||||||
if (this.currentItem.name !== item.name) {
|
|
||||||
this.audio.pause()
|
|
||||||
this.audio.src = item.mp3
|
|
||||||
this.audio.currentTime = 0
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.audio.pause()
|
|
||||||
this.audio.src = item.mp3
|
|
||||||
this.audio.currentTime = 0
|
|
||||||
}
|
|
||||||
this.audio.play()
|
|
||||||
this.audio.addEventListener('ended', () => (item.is_play = false))
|
|
||||||
} else {
|
|
||||||
this.stopPlay()
|
|
||||||
}
|
|
||||||
this.currentItem = item
|
|
||||||
},
|
|
||||||
stopPlay() {
|
|
||||||
this.audio.pause()
|
|
||||||
// this.audio.currentTime = 0
|
|
||||||
this.audio.removeEventListener('ended', null)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
unmounted() {
|
|
||||||
this.stopPlay()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function togglePlay(item, list) {
|
||||||
|
list.map((v) => {
|
||||||
|
if (v.name !== item.name) {
|
||||||
|
v.is_play = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
item.is_play = !item.is_play
|
||||||
|
if (item.is_play) {
|
||||||
|
if (data.currentItem) {
|
||||||
|
if (data.currentItem.name !== item.name) {
|
||||||
|
data.audio.pause()
|
||||||
|
data.audio.src = item.mp3
|
||||||
|
data.audio.currentTime = 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data.audio.pause()
|
||||||
|
data.audio.src = item.mp3
|
||||||
|
data.audio.currentTime = 0
|
||||||
|
}
|
||||||
|
data.audio.play()
|
||||||
|
data.audio.addEventListener('ended', () => (item.is_play = false))
|
||||||
|
} else {
|
||||||
|
stopPlay()
|
||||||
|
}
|
||||||
|
data.currentItem = item
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopPlay() {
|
||||||
|
data.audio.pause()
|
||||||
|
// data.audio.currentTime = 0
|
||||||
|
data.audio.removeEventListener('ended', null)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
|||||||
@ -7,63 +7,59 @@
|
|||||||
</BaseHeader>
|
</BaseHeader>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<Scroll class="Scroll" @pulldown="loadData">
|
<Scroll class="Scroll" @pulldown="loadData">
|
||||||
<Posters mode="music" :list="videos" />
|
<Posters mode="music" :list="data.videos" />
|
||||||
<Loading :is-full-screen="false" v-if="loading" />
|
<Loading :is-full-screen="false" v-if="data.loading" />
|
||||||
<NoMore v-else />
|
<NoMore v-else />
|
||||||
</Scroll>
|
</Scroll>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import Posters from '../../../components/Posters'
|
import Posters from '@/components/Posters.vue'
|
||||||
import Scroll from '../../../components/Scroll'
|
import Scroll from '@/components/Scroll.vue'
|
||||||
import { myVideo } from '@/api/videos'
|
import { myVideo } from '@/api/videos'
|
||||||
|
|
||||||
export default {
|
import { onMounted, reactive } from 'vue'
|
||||||
name: 'VideoCollect',
|
|
||||||
components: {
|
defineOptions({
|
||||||
Posters,
|
name: 'VideoCollect'
|
||||||
Scroll
|
})
|
||||||
},
|
|
||||||
data() {
|
const data = reactive({
|
||||||
return {
|
loading: false,
|
||||||
loading: false,
|
total: 0,
|
||||||
total: 0,
|
pageNo: 0,
|
||||||
pageNo: 0,
|
pageSize: 15,
|
||||||
pageSize: 15,
|
videos: []
|
||||||
videos: []
|
})
|
||||||
}
|
|
||||||
},
|
onMounted(() => {
|
||||||
computed: {},
|
loadData(true)
|
||||||
created() {
|
})
|
||||||
this.loadData(true)
|
|
||||||
},
|
async function loadData(init = false) {
|
||||||
methods: {
|
if (data.loading) return
|
||||||
async loadData(init = false) {
|
if (!init) {
|
||||||
if (this.loading) return
|
if (data.total <= data.videos.length) {
|
||||||
if (!init) {
|
return
|
||||||
if (this.total <= this.videos.length) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.pageNo++
|
|
||||||
}
|
|
||||||
this.loading = true
|
|
||||||
let res = await myVideo({
|
|
||||||
pageNo: this.pageNo,
|
|
||||||
pageSize: this.pageSize
|
|
||||||
})
|
|
||||||
this.loading = false
|
|
||||||
if (res.code === this.SUCCESS) {
|
|
||||||
this.videos = this.videos.concat(res.data.list)
|
|
||||||
this.total = res.data.total
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
data.pageNo++
|
||||||
|
}
|
||||||
|
data.loading = true
|
||||||
|
let res: any = await myVideo({
|
||||||
|
pageNo: data.pageNo,
|
||||||
|
pageSize: data.pageSize
|
||||||
|
})
|
||||||
|
data.loading = false
|
||||||
|
if (res.success) {
|
||||||
|
data.videos = data.videos.concat(res.data.list)
|
||||||
|
data.total = res.data.total
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
@import '../../../assets/less/index';
|
@import '@/assets/less/index';
|
||||||
|
|
||||||
.VideoCollect {
|
.VideoCollect {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|||||||
@ -13,16 +13,16 @@
|
|||||||
style="width: calc(100vw - 2rem); margin-left: 1rem"
|
style="width: calc(100vw - 2rem); margin-left: 1rem"
|
||||||
tabStyleWidth="50%"
|
tabStyleWidth="50%"
|
||||||
:tabTexts="['视频', '影视综']"
|
:tabTexts="['视频', '影视综']"
|
||||||
v-model:active-index="currentSlideItemIndex"
|
v-model:active-index="data.currentSlideItemIndex"
|
||||||
>
|
>
|
||||||
</Indicator>
|
</Indicator>
|
||||||
<SlideHorizontal v-model:index="currentSlideItemIndex" class="SlideRowList">
|
<SlideHorizontal v-model:index="data.currentSlideItemIndex" class="SlideRowList">
|
||||||
<SlideItem class="tab1" style="overflow: auto">
|
<SlideItem class="tab1" style="overflow: auto">
|
||||||
<Scroll class="Scroll" @pulldown="getHistoryVideo">
|
<Scroll class="Scroll" @pulldown="getHistoryVideo">
|
||||||
<Posters :list="historyVideo.list" v-if="historyVideo.total"></Posters>
|
<Posters :list="data.historyVideo.list" v-if="data.historyVideo.total"></Posters>
|
||||||
<Loading :is-full-screen="false" v-if="loadingVideo" />
|
<Loading :is-full-screen="false" v-if="data.loadingVideo" />
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<NoMore v-if="historyVideo.list.length" />
|
<NoMore v-if="data.historyVideo.list.length" />
|
||||||
<div class="empty" v-else>
|
<div class="empty" v-else>
|
||||||
<img src="../../../assets/img/icon/none-bg1.webp" alt="" />
|
<img src="../../../assets/img/icon/none-bg1.webp" alt="" />
|
||||||
<div class="title">暂无观看历史记录</div>
|
<div class="title">暂无观看历史记录</div>
|
||||||
@ -40,100 +40,97 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import Posters from '../../../components/Posters'
|
import Posters from '@/components/Posters.vue'
|
||||||
import Scroll from '../../../components/Scroll'
|
import Scroll from '@/components/Scroll.vue'
|
||||||
import NoMore from '../../../components/NoMore'
|
import NoMore from '@/components/NoMore.vue'
|
||||||
import { historyOther, historyVideo } from '@/api/videos'
|
import { historyOther, historyVideo } from '@/api/videos'
|
||||||
|
|
||||||
export default {
|
import { computed, onMounted, reactive } from 'vue'
|
||||||
name: 'lookHistory',
|
import { _showConfirmDialog } from '@/utils'
|
||||||
components: {
|
|
||||||
NoMore,
|
defineOptions({
|
||||||
Posters,
|
name: 'LookHistory'
|
||||||
Scroll
|
})
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
loadingVideo: false,
|
||||||
|
loadingOther: false,
|
||||||
|
isClearHistoryVideo: false,
|
||||||
|
isClearHistoryOther: false,
|
||||||
|
currentSlideItemIndex: 0,
|
||||||
|
pageSize: 15,
|
||||||
|
historyVideo: {
|
||||||
|
total: 0,
|
||||||
|
pageNo: 0,
|
||||||
|
list: []
|
||||||
},
|
},
|
||||||
data() {
|
historyOther: {
|
||||||
return {
|
total: 0,
|
||||||
loadingVideo: false,
|
pageNo: 0,
|
||||||
loadingOther: false,
|
list: []
|
||||||
isClearHistoryVideo: false,
|
|
||||||
isClearHistoryOther: false,
|
|
||||||
currentSlideItemIndex: 0,
|
|
||||||
pageSize: 15,
|
|
||||||
historyVideo: {
|
|
||||||
total: 0,
|
|
||||||
pageNo: 0,
|
|
||||||
list: []
|
|
||||||
},
|
|
||||||
historyOther: {
|
|
||||||
total: 0,
|
|
||||||
pageNo: 0,
|
|
||||||
list: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
isClear() {
|
|
||||||
if (this.currentSlideItemIndex === 0) {
|
|
||||||
return this.historyVideo.list.length
|
|
||||||
}
|
|
||||||
return this.historyOther.list.length
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getHistoryVideo(true)
|
|
||||||
this.getHistoryOther(true)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async getHistoryVideo(init = false) {
|
|
||||||
if (this.loadingVideo) return
|
|
||||||
if (this.isClearHistoryVideo) return
|
|
||||||
if (!init) {
|
|
||||||
if (this.historyVideo.total <= this.historyVideo.list.length) return
|
|
||||||
this.historyVideo.pageNo++
|
|
||||||
}
|
|
||||||
this.loadingVideo = true
|
|
||||||
let res = await historyVideo({
|
|
||||||
pageNo: this.historyVideo.pageNo,
|
|
||||||
pageSize: this.pageSize
|
|
||||||
})
|
|
||||||
console.log(res)
|
|
||||||
this.loadingVideo = false
|
|
||||||
if (res.code === this.SUCCESS) {
|
|
||||||
this.historyVideo.list = this.historyVideo.list.concat(res.data.list)
|
|
||||||
this.historyVideo.total = res.data.total
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async getHistoryOther(init = false) {
|
|
||||||
if (this.loadingOther) return
|
|
||||||
if (this.isClearHistoryOther) return
|
|
||||||
this.loadingOther = true
|
|
||||||
if (!init) {
|
|
||||||
this.historyOther.pageNo++
|
|
||||||
}
|
|
||||||
let res = await historyOther({
|
|
||||||
pageNo: this.historyOther.pageNo,
|
|
||||||
pageSize: this.pageSize
|
|
||||||
})
|
|
||||||
this.loadingOther = false
|
|
||||||
if (res.code === this.SUCCESS) {
|
|
||||||
this.historyOther.list = this.historyOther.list.concat(res.data.list)
|
|
||||||
this.historyOther.total = res.data.total
|
|
||||||
}
|
|
||||||
},
|
|
||||||
clear() {
|
|
||||||
this.$showConfirmDialog('确定清空?', '清空后,以往观看记录不再展示', 'gray', () => {
|
|
||||||
if (this.currentSlideItemIndex === 0) {
|
|
||||||
this.historyVideo.list = []
|
|
||||||
this.isClearHistoryVideo = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.historyOther.list = []
|
|
||||||
this.isClearHistoryVideo = true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const isClear = computed(() => {
|
||||||
|
if (data.currentSlideItemIndex === 0) {
|
||||||
|
return data.historyVideo.list.length
|
||||||
|
}
|
||||||
|
return data.historyOther.list.length
|
||||||
|
})
|
||||||
|
onMounted(() => {
|
||||||
|
getHistoryVideo(true)
|
||||||
|
getHistoryOther(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
async function getHistoryVideo(init = false) {
|
||||||
|
if (data.loadingVideo) return
|
||||||
|
if (data.isClearHistoryVideo) return
|
||||||
|
if (!init) {
|
||||||
|
if (data.historyVideo.total <= data.historyVideo.list.length) return
|
||||||
|
data.historyVideo.pageNo++
|
||||||
|
}
|
||||||
|
data.loadingVideo = true
|
||||||
|
let res: any = await historyVideo({
|
||||||
|
pageNo: data.historyVideo.pageNo,
|
||||||
|
pageSize: data.pageSize
|
||||||
|
})
|
||||||
|
console.log(res)
|
||||||
|
data.loadingVideo = false
|
||||||
|
if (res.success) {
|
||||||
|
data.historyVideo.list = data.historyVideo.list.concat(res.data.list)
|
||||||
|
data.historyVideo.total = res.data.total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getHistoryOther(init = false) {
|
||||||
|
if (data.loadingOther) return
|
||||||
|
if (data.isClearHistoryOther) return
|
||||||
|
data.loadingOther = true
|
||||||
|
if (!init) {
|
||||||
|
data.historyOther.pageNo++
|
||||||
|
}
|
||||||
|
let res: any = await historyOther({
|
||||||
|
pageNo: data.historyOther.pageNo,
|
||||||
|
pageSize: data.pageSize
|
||||||
|
})
|
||||||
|
data.loadingOther = false
|
||||||
|
if (res.success) {
|
||||||
|
data.historyOther.list = data.historyOther.list.concat(res.data.list)
|
||||||
|
data.historyOther.total = res.data.total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
_showConfirmDialog('确定清空?', '清空后,以往观看记录不再展示', 'gray', () => {
|
||||||
|
if (data.currentSlideItemIndex === 0) {
|
||||||
|
data.historyVideo.list = []
|
||||||
|
data.isClearHistoryVideo = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data.historyOther.list = []
|
||||||
|
data.isClearHistoryVideo = true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -1,35 +1,35 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="DetailSetting">
|
<div class="DetailSetting">
|
||||||
<BaseHeader />
|
<BaseHeader />
|
||||||
<div class="content type1" v-if="type === 0">
|
<div class="content type1" v-if="data.type === 0">
|
||||||
<div class="notice">
|
<div class="notice">
|
||||||
<img src="../../../../assets/img/icon/newicon/left_menu/lock.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/lock.png" alt="" />
|
||||||
<span>时间锁已关闭</span>
|
<span>时间锁已关闭</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt1r no-active">
|
<div class="row mt1r no-active">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../../assets/img/icon/newicon/left_menu/hourglass.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/hourglass.png" alt="" />
|
||||||
<span>可为时间锁设置一个触发时间</span>
|
<span>可为时间锁设置一个触发时间</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt1r no-active">
|
<div class="row mt1r no-active">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../../assets/img/icon/newicon/left_menu/clock.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/clock.png" alt="" />
|
||||||
<span>开启时间锁后,单日使用时长超过触发时间,需输入密码才能继续使用</span>
|
<span>开启时间锁后,单日使用时长超过触发时间,需输入密码才能继续使用</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt1r mb1r no-active">
|
<div class="row mt1r mb1r no-active">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../../assets/img/icon/newicon/left_menu/lock.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/lock.png" alt="" />
|
||||||
<span>开启时间锁,需先设置独立密码;忘记密码后可通过申诉重置密码</span>
|
<span>开启时间锁,需先设置独立密码;忘记密码后可通过申诉重置密码</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt1r mb1r" @click="$nav('trigger-time', { triggerTime })">
|
<div class="row mt1r mb1r" @click="nav('trigger-time', { triggerTime: data.triggerTime })">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<span>触发时间</span>
|
<span>触发时间</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>{{ triggerTime }}分钟</span>
|
<span>{{ data.triggerTime }}分钟</span>
|
||||||
<dy-back direction="right"></dy-back>
|
<dy-back direction="right"></dy-back>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -37,62 +37,62 @@
|
|||||||
<div class="button primary">开启时间锁</div>
|
<div class="button primary">开启时间锁</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content type2" v-if="type === 1">
|
<div class="content type2" v-if="data.type === 1">
|
||||||
<img
|
<img class="desc" src="@/assets/img/icon/newicon/left_menu/qingshaonian.png" alt="" />
|
||||||
class="desc"
|
|
||||||
src="../../../../assets/img/icon/newicon/left_menu/qingshaonian.png"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<div class="notice">
|
<div class="notice">
|
||||||
<span>更多信息可阅读</span>
|
<span>更多信息可阅读</span>
|
||||||
<span
|
<span
|
||||||
style="color: yellow"
|
style="color: yellow"
|
||||||
@click="$nav('/service-protocol', { type: '儿童/青少年使用须知' })"
|
@click="nav('/service-protocol', { type: '儿童/青少年使用须知' })"
|
||||||
>《儿童/青少年使用须知》</span
|
>《儿童/青少年使用须知》</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="button primary">开启青少年模式</div>
|
<div class="button primary">开启青少年模式</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content type2" v-if="type === 2">
|
<div class="content type2" v-if="data.type === 2">
|
||||||
<img class="desc" src="../../../../assets/img/icon/newicon/left_menu/img-type3.png" alt="" />
|
<img class="desc" src="@/assets/img/icon/newicon/left_menu/img-type3.png" alt="" />
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<div class="notice">
|
<div class="notice">
|
||||||
<!-- TODO 有个勾选没做-->
|
<!-- TODO 有个勾选没做-->
|
||||||
<span>我已阅读并接受</span>
|
<span>我已阅读并接受</span>
|
||||||
<span
|
<span
|
||||||
style="color: yellow"
|
style="color: yellow"
|
||||||
@click="$nav('/service-protocol', { type: '抖音亲子平台服务协议' })"
|
@click="nav('/service-protocol', { type: '抖音亲子平台服务协议' })"
|
||||||
>
|
>
|
||||||
《抖音亲子平台服务协议》
|
《抖音亲子平台服务协议》
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="button primary">立即绑定</div>
|
<BaseButton type="primary">立即绑定</BaseButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import enums from '../../../../utils/enums'
|
import enums from '@/utils/enums'
|
||||||
|
|
||||||
export default {
|
import { onMounted, reactive } from 'vue'
|
||||||
name: 'DetailSetting',
|
import { useNav } from '@/utils/hooks/useNav.js'
|
||||||
data() {
|
import { useRoute } from 'vue-router'
|
||||||
return {
|
import BaseButton from '@/components/BaseButton.vue'
|
||||||
type: 0,
|
|
||||||
enums,
|
defineOptions({
|
||||||
triggerTime: enums.TRIGGER_TIME.TIME60
|
name: 'DetailSetting'
|
||||||
}
|
})
|
||||||
},
|
|
||||||
computed: {},
|
const route = useRoute()
|
||||||
created() {
|
const nav = useNav()
|
||||||
this.type = ~~this.$route.query.type
|
const data = reactive({
|
||||||
let triggerTime = localStorage.getItem('changeTriggerTime')
|
type: 0,
|
||||||
if (triggerTime !== null) this.triggerTime = triggerTime
|
triggerTime: enums.TRIGGER_TIME.TIME60
|
||||||
},
|
})
|
||||||
methods: {}
|
|
||||||
}
|
onMounted(() => {
|
||||||
|
data.type = ~~route.query.type
|
||||||
|
let triggerTime = localStorage.getItem('changeTriggerTime')
|
||||||
|
if (triggerTime !== null) data.triggerTime = Number(triggerTime)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
|||||||
@ -6,21 +6,21 @@
|
|||||||
</template>
|
</template>
|
||||||
</BaseHeader>
|
</BaseHeader>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="row" @click="$nav('detail-setting', { type: 0 })">
|
<div class="row" @click="nav('detail-setting', { type: 0 })">
|
||||||
<div class="left">时间锁</div>
|
<div class="left">时间锁</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>未开启</span>
|
<span>未开启</span>
|
||||||
<dy-back direction="right"></dy-back>
|
<dy-back direction="right"></dy-back>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="$nav('detail-setting', { type: 1 })">
|
<div class="row" @click="nav('detail-setting', { type: 1 })">
|
||||||
<div class="left">青少年模式</div>
|
<div class="left">青少年模式</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>未开启</span>
|
<span>未开启</span>
|
||||||
<dy-back direction="right"></dy-back>
|
<dy-back direction="right"></dy-back>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="$nav('detail-setting', { type: 2 })">
|
<div class="row" @click="nav('detail-setting', { type: 2 })">
|
||||||
<div class="left">亲子平台</div>
|
<div class="left">亲子平台</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>未开启</span>
|
<span>未开启</span>
|
||||||
@ -30,20 +30,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
export default {
|
import { useNav } from '@/utils/hooks/useNav'
|
||||||
name: 'index',
|
|
||||||
data() {
|
defineOptions({
|
||||||
return {}
|
name: 'MinorProtection'
|
||||||
},
|
})
|
||||||
computed: {},
|
const nav = useNav()
|
||||||
created() {},
|
|
||||||
methods: {}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
@import '../../../../assets/less/index';
|
@import '@/assets/less/index';
|
||||||
|
|
||||||
.index {
|
.index {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|||||||
@ -8,51 +8,53 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="row" @click="setTriggerTime(enums.TRIGGER_TIME.TIME40)">
|
<div class="row" @click="setTriggerTime(enums.TRIGGER_TIME.TIME40)">
|
||||||
<div class="left">40分钟</div>
|
<div class="left">40分钟</div>
|
||||||
<div class="right" v-if="triggerTime === enums.TRIGGER_TIME.TIME40">
|
<div class="right" v-if="data.triggerTime === enums.TRIGGER_TIME.TIME40">
|
||||||
<img src="../../../../assets/img/icon/ok-red.png" alt="" />
|
<img src="../../../../assets/img/icon/ok-red.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="setTriggerTime(enums.TRIGGER_TIME.TIME60)">
|
<div class="row" @click="setTriggerTime(enums.TRIGGER_TIME.TIME60)">
|
||||||
<div class="left">60分钟</div>
|
<div class="left">60分钟</div>
|
||||||
<div class="right" v-if="triggerTime === enums.TRIGGER_TIME.TIME60">
|
<div class="right" v-if="data.triggerTime === enums.TRIGGER_TIME.TIME60">
|
||||||
<img src="../../../../assets/img/icon/ok-red.png" alt="" />
|
<img src="../../../../assets/img/icon/ok-red.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="setTriggerTime(enums.TRIGGER_TIME.TIME90)">
|
<div class="row" @click="setTriggerTime(enums.TRIGGER_TIME.TIME90)">
|
||||||
<div class="left">90分钟</div>
|
<div class="left">90分钟</div>
|
||||||
<div class="right" v-if="triggerTime === enums.TRIGGER_TIME.TIME90">
|
<div class="right" v-if="data.triggerTime === enums.TRIGGER_TIME.TIME90">
|
||||||
<img src="../../../../assets/img/icon/ok-red.png" alt="" />
|
<img src="../../../../assets/img/icon/ok-red.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="setTriggerTime(enums.TRIGGER_TIME.TIME120)">
|
<div class="row" @click="setTriggerTime(enums.TRIGGER_TIME.TIME120)">
|
||||||
<div class="left">120分钟</div>
|
<div class="left">120分钟</div>
|
||||||
<div class="right" v-if="triggerTime === enums.TRIGGER_TIME.TIME120">
|
<div class="right" v-if="data.triggerTime === enums.TRIGGER_TIME.TIME120">
|
||||||
<img src="../../../../assets/img/icon/ok-red.png" alt="" />
|
<img src="../../../../assets/img/icon/ok-red.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import enums from '../../../../utils/enums'
|
import enums from '../../../../utils/enums'
|
||||||
|
|
||||||
export default {
|
import { onMounted, reactive } from 'vue'
|
||||||
name: 'TriggerTime',
|
import { useRoute } from 'vue-router'
|
||||||
data() {
|
|
||||||
return {
|
defineOptions({
|
||||||
enums,
|
name: 'ChooseSchool'
|
||||||
triggerTime: enums.TRIGGER_TIME.TIME60
|
})
|
||||||
}
|
|
||||||
},
|
const route = useRoute()
|
||||||
created() {
|
const data = reactive({
|
||||||
this.triggerTime = ~~this.$route.query.triggerTime
|
triggerTime: enums.TRIGGER_TIME.TIME60
|
||||||
},
|
})
|
||||||
methods: {
|
|
||||||
setTriggerTime(type) {
|
onMounted(() => {
|
||||||
this.triggerTime = type
|
data.triggerTime = ~~route.query.triggerTime
|
||||||
localStorage.setItem('changeTriggerTime', type)
|
})
|
||||||
}
|
|
||||||
}
|
function setTriggerTime(type) {
|
||||||
|
data.triggerTime = type
|
||||||
|
localStorage.setItem('changeTriggerTime', type)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
<div class="title">帐号</div>
|
<div class="title">帐号</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../assets/img/icon/newicon/left_menu/user.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/user.png" alt="" />
|
||||||
<span>帐号与安全</span>
|
<span>帐号与安全</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -18,7 +18,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../assets/img/icon/newicon/left_menu/lock.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/lock.png" alt="" />
|
||||||
<span>隐私设置</span>
|
<span>隐私设置</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -30,7 +30,7 @@
|
|||||||
<div class="title">通用</div>
|
<div class="title">通用</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../assets/img/icon/newicon/left_menu/remind.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/remind.png" alt="" />
|
||||||
<span>通知设置</span>
|
<span>通知设置</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -39,7 +39,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../assets/img/icon/newicon/left_menu/dynamics.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/dynamics.png" alt="" />
|
||||||
<span>动态壁纸</span>
|
<span>动态壁纸</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -48,7 +48,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../assets/img/icon/newicon/left_menu/setting-two.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/setting-two.png" alt="" />
|
||||||
<span>通用设置</span>
|
<span>通用设置</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -60,7 +60,7 @@
|
|||||||
<div class="title">帐号互通</div>
|
<div class="title">帐号互通</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../assets/img/icon/newicon/left_menu/toutiao.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/toutiao.png" alt="" />
|
||||||
<span>头条主页</span>
|
<span>头条主页</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -72,7 +72,7 @@
|
|||||||
<div class="title">关于</div>
|
<div class="title">关于</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../assets/img/icon/newicon/left_menu/adddddddd.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/adddddddd.png" alt="" />
|
||||||
<span>广告反馈与设置</span>
|
<span>广告反馈与设置</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -81,7 +81,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../assets/img/icon/newicon/left_menu/book.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/book.png" alt="" />
|
||||||
<span>用户协议</span>
|
<span>用户协议</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -90,7 +90,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../assets/img/icon/newicon/left_menu/bookmark.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/bookmark.png" alt="" />
|
||||||
<span>社区自律公约</span>
|
<span>社区自律公约</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -99,7 +99,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../assets/img/icon/newicon/left_menu/personal-privacy.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/personal-privacy.png" alt="" />
|
||||||
<span>隐私政策</span>
|
<span>隐私政策</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -108,7 +108,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../assets/img/icon/newicon/left_menu/protect.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/protect.png" alt="" />
|
||||||
<span>应用权限</span>
|
<span>应用权限</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -117,7 +117,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../assets/img/icon/newicon/left_menu/ring.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/ring.png" alt="" />
|
||||||
<span>第三方SDK列表</span>
|
<span>第三方SDK列表</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -126,7 +126,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../assets/img/icon/newicon/left_menu/about.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/about.png" alt="" />
|
||||||
<span>关于抖音</span>
|
<span>关于抖音</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -135,7 +135,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../assets/img/icon/newicon/left_menu/feedback.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/feedback.png" alt="" />
|
||||||
<span>反馈与帮助</span>
|
<span>反馈与帮助</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -144,7 +144,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../assets/img/icon/newicon/left_menu/delete.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/delete.png" alt="" />
|
||||||
<span>清理占用空间</span>
|
<span>清理占用空间</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -155,7 +155,7 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../assets/img/icon/newicon/left_menu/switch.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/switch.png" alt="" />
|
||||||
<span>切换空间</span>
|
<span>切换空间</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -164,7 +164,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../../assets/img/icon/newicon/left_menu/logout.png" alt="" />
|
<img src="@/assets/img/icon/newicon/left_menu/logout.png" alt="" />
|
||||||
<span>退出登录</span>
|
<span>退出登录</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -172,32 +172,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="version">抖音 version{{ version }}</div>
|
<div class="version">抖音 version{{ store.version }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia'
|
||||||
|
|
||||||
export default {
|
defineOptions({
|
||||||
name: 'Setting',
|
name: 'ChooseSchool'
|
||||||
setup() {
|
})
|
||||||
const baseStore = useBaseStore()
|
|
||||||
return { baseStore }
|
const store = useBaseStore()
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
version: this.baseStore.version
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {},
|
|
||||||
created() {},
|
|
||||||
methods: {}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
@import '../../../assets/less/index';
|
@import '@/assets/less/index';
|
||||||
|
|
||||||
.Setting {
|
.Setting {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|||||||
@ -11,24 +11,24 @@
|
|||||||
</template>
|
</template>
|
||||||
</BaseHeader>
|
</BaseHeader>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="row" @click="$nav('/me/choose-school')">
|
<div class="row" @click="nav('/me/choose-school')">
|
||||||
<div class="left">学校</div>
|
<div class="left">学校</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>{{ isEmpty(localSchool.name) }}</span>
|
<span>{{ isEmpty(data.localSchool.name) }}</span>
|
||||||
<dy-back scale="1" direction="right"></dy-back>
|
<dy-back scale="1" direction="right"></dy-back>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="checkGo('/me/choose-department')">
|
<div class="row" @click="checkGo('/me/choose-department')">
|
||||||
<div class="left">院系</div>
|
<div class="left">院系</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>{{ isEmpty(localSchool.department) }}</span>
|
<span>{{ isEmpty(data.localSchool.department) }}</span>
|
||||||
<dy-back scale="1" direction="right"></dy-back>
|
<dy-back scale="1" direction="right"></dy-back>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="showJoinTimeDialog">
|
<div class="row" @click="showJoinTimeDialog">
|
||||||
<div class="left">入学时间</div>
|
<div class="left">入学时间</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>{{ isEmpty(localSchool.joinTime) }}</span>
|
<span>{{ isEmpty(data.localSchool.joinTime) }}</span>
|
||||||
<dy-back scale="1" direction="right"></dy-back>
|
<dy-back scale="1" direction="right"></dy-back>
|
||||||
<div v-show="false" id="trigger1"></div>
|
<div v-show="false" id="trigger1"></div>
|
||||||
</div>
|
</div>
|
||||||
@ -36,11 +36,14 @@
|
|||||||
<div class="row" @click="showEducationDialog">
|
<div class="row" @click="showEducationDialog">
|
||||||
<div class="left">学历</div>
|
<div class="left">学历</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>{{ isEmpty(localSchool.education) }}</span>
|
<span>{{ isEmpty(data.localSchool.education) }}</span>
|
||||||
<dy-back scale="1" direction="right"></dy-back>
|
<dy-back scale="1" direction="right"></dy-back>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="$nav('/me/display-type', { displayType: localSchool.displayType })">
|
<div
|
||||||
|
class="row"
|
||||||
|
@click="nav('/me/display-type', { displayType: data.localSchool.displayType })"
|
||||||
|
>
|
||||||
<div class="left">展示范围</div>
|
<div class="left">展示范围</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>{{ displayType }}</span>
|
<span>{{ displayType }}</span>
|
||||||
@ -51,122 +54,128 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import { mapState } from 'pinia'
|
|
||||||
import enums from '../../../utils/enums'
|
import enums from '../../../utils/enums'
|
||||||
import { inject } from 'vue'
|
import { computed, onMounted, reactive } from 'vue'
|
||||||
import MobileSelect from '../../../components/mobile-select/mobile-select'
|
import MobileSelect from '../../../components/mobile-select/mobile-select'
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { useNav } from '@/utils/hooks/useNav.js'
|
||||||
|
import {
|
||||||
|
_hideLoading,
|
||||||
|
_notice,
|
||||||
|
_showLoading,
|
||||||
|
_showSelectDialog,
|
||||||
|
_showSimpleConfirmDialog,
|
||||||
|
_sleep,
|
||||||
|
cloneDeep
|
||||||
|
} from '@/utils'
|
||||||
|
|
||||||
//TODO 年份选择器没做
|
//TODO 年份选择器没做
|
||||||
export default {
|
|
||||||
name: 'AddSchool',
|
defineOptions({
|
||||||
setup() {
|
name: 'AddSchool'
|
||||||
const baseStore = useBaseStore()
|
})
|
||||||
return { baseStore }
|
|
||||||
},
|
const store = useBaseStore()
|
||||||
data() {
|
const router = useRouter()
|
||||||
return {
|
const nav = useNav()
|
||||||
mitt: inject('mitt'),
|
const data = reactive({
|
||||||
localSchool: this.$clone(this.baseStore.userinfo.school),
|
localSchool: cloneDeep(store.userinfo.school),
|
||||||
educationList: [
|
educationList: [
|
||||||
{ id: 1, name: '专科' },
|
{ id: 1, name: '专科' },
|
||||||
{ id: 2, name: '本科' },
|
{ id: 2, name: '本科' },
|
||||||
{ id: 3, name: '硕士' },
|
{ id: 3, name: '硕士' },
|
||||||
{ id: 4, name: '博士' }
|
{ id: 4, name: '博士' }
|
||||||
]
|
]
|
||||||
}
|
})
|
||||||
},
|
|
||||||
created() {
|
onMounted(() => {
|
||||||
let school = localStorage.getItem('changeSchool')
|
let school = localStorage.getItem('changeSchool')
|
||||||
let department = localStorage.getItem('changeDepartment')
|
let department = localStorage.getItem('changeDepartment')
|
||||||
let displayType = localStorage.getItem('changeDisplayType')
|
let displayType = localStorage.getItem('changeDisplayType')
|
||||||
let joinTime = localStorage.getItem('changeJoinTime')
|
let joinTime = localStorage.getItem('changeJoinTime')
|
||||||
let education = localStorage.getItem('changeEducation')
|
let education = localStorage.getItem('changeEducation')
|
||||||
if (school !== null) this.localSchool.name = school
|
if (school !== null) data.localSchool.name = school
|
||||||
if (department !== null) this.localSchool.department = department
|
if (department !== null) data.localSchool.department = department
|
||||||
if (displayType !== null) this.localSchool.displayType = ~~displayType
|
if (displayType !== null) data.localSchool.displayType = ~~displayType
|
||||||
if (joinTime !== null) this.localSchool.joinTime = ~~joinTime
|
if (joinTime !== null) data.localSchool.joinTime = ~~joinTime
|
||||||
if (education !== null) this.localSchool.education = education
|
if (education !== null) data.localSchool.education = education
|
||||||
// localStorage.clear()
|
})
|
||||||
},
|
|
||||||
computed: {
|
const school = computed(() => {
|
||||||
...mapState(useBaseStore, ['userinfo']),
|
return store.userinfo.school
|
||||||
isChanged() {
|
})
|
||||||
if (this.school.name !== this.localSchool.name) return true
|
const isChanged = computed(() => {
|
||||||
if (this.school.department !== this.localSchool.department) return true
|
if (school.value.name !== data.localSchool.name) return true
|
||||||
if (this.school.joinTime !== this.localSchool.joinTime) return true
|
if (school.value.department !== data.localSchool.department) return true
|
||||||
if (this.school.education !== this.localSchool.education) return true
|
if (school.value.joinTime !== data.localSchool.joinTime) return true
|
||||||
return this.school.displayType !== this.localSchool.displayType
|
if (school.value.education !== data.localSchool.education) return true
|
||||||
},
|
return school.value.displayType !== data.localSchool.displayType
|
||||||
displayType() {
|
})
|
||||||
if (this.localSchool.displayType === enums.DISPLAY_TYPE.ALL) return '公开可见'
|
|
||||||
if (this.localSchool.displayType === enums.DISPLAY_TYPE.SCHOOL) return '校友可见'
|
const displayType = computed(() => {
|
||||||
if (this.localSchool.displayType === enums.DISPLAY_TYPE.ME) return '仅自己可见'
|
if (data.localSchool.displayType === enums.DISPLAY_TYPE.ALL) return '公开可见'
|
||||||
return ''
|
if (data.localSchool.displayType === enums.DISPLAY_TYPE.SCHOOL) return '校友可见'
|
||||||
},
|
if (data.localSchool.displayType === enums.DISPLAY_TYPE.ME) return '仅自己可见'
|
||||||
school() {
|
return ''
|
||||||
return this.userinfo.school
|
})
|
||||||
}
|
|
||||||
},
|
function showJoinTimeDialog() {
|
||||||
methods: {
|
new MobileSelect({
|
||||||
showJoinTimeDialog() {
|
trigger: '#trigger1',
|
||||||
new MobileSelect({
|
title: '学历',
|
||||||
trigger: '#trigger1',
|
wheels: [
|
||||||
title: '学历',
|
{
|
||||||
wheels: [
|
data: Array.apply(null, { length: 50 }).map((v, i) => new Date().getFullYear() - i)
|
||||||
{
|
|
||||||
data: Array.apply(null, { length: 50 }).map((v, i) => new Date().getFullYear() - i)
|
|
||||||
}
|
|
||||||
],
|
|
||||||
callback: (indexArr, data) => {
|
|
||||||
localStorage.setItem('changeJoinTime', data[0])
|
|
||||||
this.localSchool.joinTime = ~~data[0]
|
|
||||||
}
|
|
||||||
}).show()
|
|
||||||
},
|
|
||||||
showEducationDialog() {
|
|
||||||
this.$showSelectDialog(this.educationList, (e) => {
|
|
||||||
localStorage.setItem('changeEducation', e.name)
|
|
||||||
this.localSchool.education = e.name
|
|
||||||
})
|
|
||||||
},
|
|
||||||
isEmpty(val) {
|
|
||||||
if (val) return val
|
|
||||||
return '点击设置'
|
|
||||||
},
|
|
||||||
checkGo(path) {
|
|
||||||
if (!this.localSchool.name) return this.$notice('请先选择学校 ')
|
|
||||||
this.$nav(path)
|
|
||||||
},
|
|
||||||
back() {
|
|
||||||
if (this.isChanged) {
|
|
||||||
this.$showSimpleConfirmDialog(
|
|
||||||
'学校信息30天内只允许修改一次,是否保存修改',
|
|
||||||
this.save,
|
|
||||||
() => {
|
|
||||||
localStorage.clear()
|
|
||||||
this.$back()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
localStorage.clear()
|
|
||||||
this.$back()
|
|
||||||
}
|
}
|
||||||
},
|
],
|
||||||
async save() {
|
callback: (indexArr, data) => {
|
||||||
if (!this.isChanged) return
|
localStorage.setItem('changeJoinTime', data[0])
|
||||||
this.$showLoading()
|
data.localSchool.joinTime = ~~data[0]
|
||||||
let data = { ...this.userinfo, ...{ school: this.localSchool } }
|
|
||||||
this.baseStore.setUserinfo(data)
|
|
||||||
await this.$sleep(500)
|
|
||||||
this.$hideLoading()
|
|
||||||
localStorage.clear()
|
|
||||||
this.$back()
|
|
||||||
this.$notice('修改成功')
|
|
||||||
}
|
}
|
||||||
|
}).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
function showEducationDialog() {
|
||||||
|
_showSelectDialog(data.educationList, (e) => {
|
||||||
|
localStorage.setItem('changeEducation', e.name)
|
||||||
|
data.localSchool.education = e.name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function isEmpty(val) {
|
||||||
|
if (val) return val
|
||||||
|
return '点击设置'
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkGo(path) {
|
||||||
|
if (!data.localSchool.name) return _notice('请先选择学校 ')
|
||||||
|
nav(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
function back() {
|
||||||
|
if (isChanged.value) {
|
||||||
|
_showSimpleConfirmDialog('学校信息30天内只允许修改一次,是否保存修改', save, () => {
|
||||||
|
localStorage.clear()
|
||||||
|
router.back()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
localStorage.clear()
|
||||||
|
router.back()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function save() {
|
||||||
|
if (!isChanged.value) return
|
||||||
|
_showLoading()
|
||||||
|
store.userinfo = { ...store.userinfo, ...{ school: data.localSchool } }
|
||||||
|
await _sleep(500)
|
||||||
|
_hideLoading()
|
||||||
|
localStorage.clear()
|
||||||
|
router.back()
|
||||||
|
_notice('修改成功')
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
</BaseHeader>
|
</BaseHeader>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="schools">
|
<div class="schools">
|
||||||
<div class="row" @click="save(item)" :key="i" v-for="(item, i) in list">
|
<div class="row" @click="save()" :key="i" v-for="(item, i) in list">
|
||||||
<span>{{ item }}</span>
|
<span>{{ item }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -15,56 +15,59 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import { mapState } from 'pinia'
|
import { ref } from 'vue'
|
||||||
|
import { _hideLoading, _showLoading, _sleep } from '@/utils'
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia'
|
||||||
|
|
||||||
export default {
|
defineOptions({
|
||||||
name: 'ChooseProvince',
|
name: 'ChooseCity'
|
||||||
setup() {
|
})
|
||||||
const baseStore = useBaseStore()
|
|
||||||
return { baseStore }
|
const store = useBaseStore()
|
||||||
},
|
const list = ref([
|
||||||
data() {
|
'河北',
|
||||||
return {
|
'山西',
|
||||||
list: [
|
'辽宁',
|
||||||
'成都',
|
'吉林',
|
||||||
'自贡',
|
'黑龙江',
|
||||||
'攀枝花',
|
'江苏',
|
||||||
'泸州',
|
'浙江',
|
||||||
'德阳',
|
'安徽',
|
||||||
'绵阳',
|
'福建',
|
||||||
'广元',
|
'江西',
|
||||||
'遂宁',
|
'山东',
|
||||||
'内江',
|
'河南',
|
||||||
'乐山',
|
'湖北',
|
||||||
'南充',
|
'湖南',
|
||||||
'眉山',
|
'广东',
|
||||||
'宜宾',
|
'海南',
|
||||||
'广安',
|
'四川',
|
||||||
'达州',
|
'贵州',
|
||||||
'雅安',
|
'云南',
|
||||||
'巴中',
|
'陕西',
|
||||||
'资阳',
|
'甘肃',
|
||||||
'阿坝',
|
'青海',
|
||||||
'甘孜',
|
'台湾',
|
||||||
'凉山'
|
'内蒙古',
|
||||||
]
|
'广西',
|
||||||
}
|
'西藏',
|
||||||
},
|
'宁夏',
|
||||||
computed: {
|
'新疆',
|
||||||
...mapState(useBaseStore, ['userinfo'])
|
'北京',
|
||||||
},
|
'天津',
|
||||||
methods: {
|
'上海',
|
||||||
async save() {
|
'重庆',
|
||||||
this.$showLoading()
|
'香港',
|
||||||
let data = { ...this.userinfo, ...{ location: '中国-四川-成都' } }
|
'澳门'
|
||||||
this.baseStore.setUserinfo(data)
|
])
|
||||||
await this.$sleep(500)
|
|
||||||
this.$hideLoading()
|
async function save() {
|
||||||
history.go(-3)
|
_showLoading()
|
||||||
}
|
store.userinfo = { ...store.userinfo, ...{ location: '中国-四川-成都' } }
|
||||||
}
|
await _sleep(500)
|
||||||
|
_hideLoading()
|
||||||
|
history.go(-3)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -5,12 +5,17 @@
|
|||||||
<span class="f16">选择院系</span>
|
<span class="f16">选择院系</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:right>
|
<template v-slot:right>
|
||||||
<span class="f14" @click="$nav('/me/declare-school', { type: 2 })">没有找到?</span>
|
<span class="f14" @click="nav('/me/declare-school', { type: 2 })">没有找到?</span>
|
||||||
</template>
|
</template>
|
||||||
</BaseHeader>
|
</BaseHeader>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="nearby">
|
<div class="nearby">
|
||||||
<div class="item" :key="i" v-for="(item, i) in departments" @click="setDepartment(item)">
|
<div
|
||||||
|
class="item"
|
||||||
|
:key="i"
|
||||||
|
v-for="(item, i) in data.departments"
|
||||||
|
@click="setDepartment(item)"
|
||||||
|
>
|
||||||
{{ item }}
|
{{ item }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -18,33 +23,36 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
export default {
|
import { onMounted, reactive } from 'vue'
|
||||||
name: 'ChooseSchool',
|
import { useNav } from '@/utils/hooks/useNav.js'
|
||||||
components: {},
|
import { useRouter } from 'vue-router'
|
||||||
data() {
|
|
||||||
return {
|
defineOptions({
|
||||||
departments: [],
|
name: 'ChooseDepartment'
|
||||||
schoolName: ''
|
})
|
||||||
}
|
|
||||||
},
|
const router = useRouter()
|
||||||
computed: {},
|
const nav = useNav()
|
||||||
created() {
|
const data = reactive({
|
||||||
for (let i = 0; i < 5; i++) {
|
departments: [],
|
||||||
this.departments.push('院系' + i)
|
schoolName: ''
|
||||||
}
|
})
|
||||||
},
|
|
||||||
methods: {
|
onMounted(() => {
|
||||||
setDepartment(val) {
|
for (let i = 0; i < 5; i++) {
|
||||||
localStorage.setItem('changeDepartment', val)
|
data.departments.push('院系' + i)
|
||||||
this.$back()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function setDepartment(val) {
|
||||||
|
localStorage.setItem('changeDepartment', val)
|
||||||
|
router.back()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
@import '../../../assets/less/index';
|
@import '@/assets/less/index';
|
||||||
|
|
||||||
.choose-school {
|
.choose-school {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@
|
|||||||
</BaseHeader>
|
</BaseHeader>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="schools">
|
<div class="schools">
|
||||||
<div class="row" @click="$nav('/me/choose-city')" :key="i" v-for="(item, i) in list">
|
<div class="row" @click="nav('/me/choose-city')" :key="i" v-for="(item, i) in list">
|
||||||
<span>{{ item }}</span>
|
<span>{{ item }}</span>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<dy-back scale=".8" direction="right"></dy-back>
|
<dy-back scale=".8" direction="right"></dy-back>
|
||||||
@ -18,50 +18,51 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
export default {
|
import { ref } from 'vue'
|
||||||
name: 'ChooseProvince',
|
import { useNav } from '@/utils/hooks/useNav.js'
|
||||||
data() {
|
|
||||||
return {
|
defineOptions({
|
||||||
list: [
|
name: 'ChooseProvince'
|
||||||
'河北',
|
})
|
||||||
'山西',
|
|
||||||
'辽宁',
|
const nav = useNav()
|
||||||
'吉林',
|
const list = ref([
|
||||||
'黑龙江',
|
'河北',
|
||||||
'江苏',
|
'山西',
|
||||||
'浙江',
|
'辽宁',
|
||||||
'安徽',
|
'吉林',
|
||||||
'福建',
|
'黑龙江',
|
||||||
'江西',
|
'江苏',
|
||||||
'山东',
|
'浙江',
|
||||||
'河南',
|
'安徽',
|
||||||
'湖北',
|
'福建',
|
||||||
'湖南',
|
'江西',
|
||||||
'广东',
|
'山东',
|
||||||
'海南',
|
'河南',
|
||||||
'四川',
|
'湖北',
|
||||||
'贵州',
|
'湖南',
|
||||||
'云南',
|
'广东',
|
||||||
'陕西',
|
'海南',
|
||||||
'甘肃',
|
'四川',
|
||||||
'青海',
|
'贵州',
|
||||||
'台湾',
|
'云南',
|
||||||
'内蒙古',
|
'陕西',
|
||||||
'广西',
|
'甘肃',
|
||||||
'西藏',
|
'青海',
|
||||||
'宁夏',
|
'台湾',
|
||||||
'新疆',
|
'内蒙古',
|
||||||
'北京',
|
'广西',
|
||||||
'天津',
|
'西藏',
|
||||||
'上海',
|
'宁夏',
|
||||||
'重庆',
|
'新疆',
|
||||||
'香港',
|
'北京',
|
||||||
'澳门'
|
'天津',
|
||||||
]
|
'上海',
|
||||||
}
|
'重庆',
|
||||||
}
|
'香港',
|
||||||
}
|
'澳门'
|
||||||
|
])
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
|||||||
@ -5,45 +5,50 @@
|
|||||||
<span class="f16">添加学校</span>
|
<span class="f16">添加学校</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:right>
|
<template v-slot:right>
|
||||||
<span class="f14" @click="$nav('/me/declare-school', { type: 1 })">没有找到?</span>
|
<span class="f14" @click="nav('/me/declare-school', { type: 1 })">没有找到?</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:bottom>
|
<template v-slot:bottom>
|
||||||
<Search
|
<Search
|
||||||
class="mt1r mb1r ml2r mr2r"
|
class="mt1r mb1r ml2r mr2r"
|
||||||
placeholder="搜索大学名称"
|
placeholder="搜索大学名称"
|
||||||
v-model="schoolName"
|
v-model="data.schoolName"
|
||||||
@clear="isSearch = false"
|
@clear="data.isSearch = false"
|
||||||
:is-show-right-text="true"
|
:is-show-right-text="true"
|
||||||
@notice="search"
|
@notice="search"
|
||||||
></Search>
|
></Search>
|
||||||
</template>
|
</template>
|
||||||
</BaseHeader>
|
</BaseHeader>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="nearby" v-if="!isSearch">
|
<div class="nearby" v-if="!data.isSearch">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<img src="../../../assets/img/icon/location.svg" alt="" />
|
<img src="../../../assets/img/icon/location.svg" alt="" />
|
||||||
<span>离我最近</span>
|
<span>离我最近</span>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="nearby.length">
|
<template v-if="data.nearby.length">
|
||||||
<div class="item" :key="i" v-for="(item, i) in nearby" @click="setSchool(item)">
|
<div class="item" :key="i" v-for="(item, i) in data.nearby" @click="setSchool(item)">
|
||||||
{{ item }}
|
{{ item }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div v-else class="item">无法获取</div>
|
<div v-else class="item">无法获取</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="line" style="width: calc(100% - 40rem); margin-left: 20rem"></div>
|
<div class="line" style="width: calc(100% - 40rem); margin-left: 20rem"></div>
|
||||||
<div class="schools" v-if="!isSearch">
|
<div class="schools" v-if="!data.isSearch">
|
||||||
<div class="item" :key="i" v-for="(item, i) in schools" @click="setSchool(item)">
|
<div class="item" :key="i" v-for="(item, i) in data.schools" @click="setSchool(item)">
|
||||||
{{ item }}
|
{{ item }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isSearch">
|
<div v-if="data.isSearch">
|
||||||
<template v-if="searchSchools.length">
|
<template v-if="data.searchSchools.length">
|
||||||
<div class="item" :key="i" v-for="(item, i) in searchSchools" @click="setSchool(item)">
|
<div
|
||||||
<span v-if="item.indexOf(schoolName) > -1">
|
class="item"
|
||||||
{{ item.substr(0, item.indexOf(schoolName)) }}
|
:key="i"
|
||||||
<span style="color: #f50">{{ schoolName }}</span>
|
v-for="(item, i) in data.searchSchools"
|
||||||
{{ item.substr(item.indexOf(schoolName) + schoolName.length) }}
|
@click="setSchool(item)"
|
||||||
|
>
|
||||||
|
<span v-if="item.indexOf(data.schoolName) > -1">
|
||||||
|
{{ item.substr(0, item.indexOf(data.schoolName)) }}
|
||||||
|
<span style="color: #f50">{{ data.schoolName }}</span>
|
||||||
|
{{ item.substr(item.indexOf(data.schoolName) + data.schoolName.length) }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else>{{ item }}</span>
|
<span v-else>{{ item }}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -52,48 +57,50 @@
|
|||||||
<img src="../../../assets/img/icon/head-image.jpeg" alt="" />
|
<img src="../../../assets/img/icon/head-image.jpeg" alt="" />
|
||||||
<div class="title">搜索结果为空</div>
|
<div class="title">搜索结果为空</div>
|
||||||
<div class="sub-title">没有搜索到相关的内容</div>
|
<div class="sub-title">没有搜索到相关的内容</div>
|
||||||
<div class="btn" @click="$nav('/me/declare-school')">没有学校信息?去申报</div>
|
<div class="btn" @click="nav('/me/declare-school')">没有学校信息?去申报</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import Search from '../../../components/Search'
|
import Search from '../../../components/Search.vue'
|
||||||
|
import { onMounted, reactive } from 'vue'
|
||||||
|
import { useNav } from '@/utils/hooks/useNav.js'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
export default {
|
defineOptions({
|
||||||
name: 'ChooseSchool',
|
name: 'ChooseSchool'
|
||||||
components: {
|
})
|
||||||
Search
|
|
||||||
},
|
const router = useRouter()
|
||||||
data() {
|
const nav = useNav()
|
||||||
return {
|
const data = reactive({
|
||||||
isSearch: false,
|
isSearch: false,
|
||||||
nearby: [],
|
nearby: [],
|
||||||
schools: [],
|
schools: [],
|
||||||
searchSchools: [],
|
searchSchools: [],
|
||||||
schoolName: ''
|
schoolName: ''
|
||||||
}
|
})
|
||||||
},
|
|
||||||
created() {
|
onMounted(() => {
|
||||||
for (let i = 0; i < 20; i++) {
|
for (let i = 0; i < 20; i++) {
|
||||||
this.nearby.push('附近大学' + i)
|
data.nearby.push('附近大学' + i)
|
||||||
this.schools.push('所有大学' + i)
|
data.schools.push('所有大学' + i)
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
setSchool(val) {
|
|
||||||
localStorage.setItem('changeSchool', val)
|
|
||||||
this.$back()
|
|
||||||
},
|
|
||||||
search() {
|
|
||||||
if (!this.schoolName.length) return (this.isSearch = false)
|
|
||||||
this.isSearch = true
|
|
||||||
let all = this.nearby.concat(this.schools)
|
|
||||||
this.searchSchools = all.filter((v) => v.includes(this.schoolName))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function setSchool(val) {
|
||||||
|
localStorage.setItem('changeSchool', val)
|
||||||
|
router.back()
|
||||||
|
}
|
||||||
|
|
||||||
|
function search() {
|
||||||
|
if (!data.schoolName.length) return (data.isSearch = false)
|
||||||
|
data.isSearch = true
|
||||||
|
let all = data.nearby.concat(data.schools)
|
||||||
|
data.searchSchools = all.filter((v) => v.includes(data.schoolName))
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -8,13 +8,13 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="label">学校全称</div>
|
<div class="label">学校全称</div>
|
||||||
<input type="text" placeholder="请输入学校全称(必填)" v-model="form.name" />
|
<input type="text" placeholder="请输入学校全称(必填)" v-model="data.form.name" />
|
||||||
</div>
|
</div>
|
||||||
<div class="row" v-if="type === 1">
|
<div class="row" v-if="data.type === 1">
|
||||||
<div class="label">所在城市</div>
|
<div class="label">所在城市</div>
|
||||||
<input type="text" placeholder="请输入学校所在城市(必填)" v-model="form.location" />
|
<input type="text" placeholder="请输入学校所在城市(必填)" v-model="data.form.location" />
|
||||||
</div>
|
</div>
|
||||||
<div class="department-row" v-if="type === 2">
|
<div class="department-row" v-if="data.type === 2">
|
||||||
<div class="label">信息问题</div>
|
<div class="label">信息问题</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>点击选择(必选)</span>
|
<span>点击选择(必选)</span>
|
||||||
@ -27,32 +27,37 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
|
import { onMounted, reactive } from 'vue'
|
||||||
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
import { _notice } from '@/utils'
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'DeclareSchool'
|
||||||
|
})
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
const data = reactive({
|
||||||
|
form: {
|
||||||
|
name: '',
|
||||||
|
location: '',
|
||||||
|
departmentInfoType: ''
|
||||||
|
},
|
||||||
|
type: 1
|
||||||
|
})
|
||||||
|
|
||||||
//TODO 院系点击那个弹窗没做
|
//TODO 院系点击那个弹窗没做
|
||||||
export default {
|
onMounted(() => {
|
||||||
name: 'DeclareSchool',
|
data.type = Number(route.query.type)
|
||||||
data() {
|
})
|
||||||
return {
|
|
||||||
form: {
|
function submit() {
|
||||||
name: '',
|
if (!data.form.name) return _notice('请输入学校全称')
|
||||||
location: '',
|
if (data.type === 1 && !data.form.location) return _notice('请输入学校所在城市')
|
||||||
departmentInfoType: ''
|
if (data.type === 2 && !data.form.departmentInfoType) return _notice('请选择信息问题')
|
||||||
},
|
_notice('申报成功')
|
||||||
type: 1
|
setTimeout(router.back, 1000)
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.type = Number(this.$route.query.type)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
submit() {
|
|
||||||
if (!this.form.name) return this.$notice('请输入学校全称')
|
|
||||||
if (this.type === 1 && !this.form.location) return this.$notice('请输入学校所在城市')
|
|
||||||
if (this.type === 2 && !this.form.departmentInfoType) return this.$notice('请选择信息问题')
|
|
||||||
this.$notice('申报成功')
|
|
||||||
setTimeout(this.$back, 1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -8,46 +8,49 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="row" @click="setDisplayType(enums.DISPLAY_TYPE.ALL)">
|
<div class="row" @click="setDisplayType(enums.DISPLAY_TYPE.ALL)">
|
||||||
<div class="left">公开可见</div>
|
<div class="left">公开可见</div>
|
||||||
<div class="right" v-if="displayType === enums.DISPLAY_TYPE.ALL">
|
<div class="right" v-if="data.displayType === enums.DISPLAY_TYPE.ALL">
|
||||||
<img src="../../../assets/img/icon/ok-red.png" alt="" />
|
<img src="../../../assets/img/icon/ok-red.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="setDisplayType(enums.DISPLAY_TYPE.SCHOOL)">
|
<div class="row" @click="setDisplayType(enums.DISPLAY_TYPE.SCHOOL)">
|
||||||
<div class="left">校友可见</div>
|
<div class="left">校友可见</div>
|
||||||
<div class="right" v-if="displayType === enums.DISPLAY_TYPE.SCHOOL">
|
<div class="right" v-if="data.displayType === enums.DISPLAY_TYPE.SCHOOL">
|
||||||
<img src="../../../assets/img/icon/ok-red.png" alt="" />
|
<img src="../../../assets/img/icon/ok-red.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="setDisplayType(enums.DISPLAY_TYPE.ME)">
|
<div class="row" @click="setDisplayType(enums.DISPLAY_TYPE.ME)">
|
||||||
<div class="left">仅自己可见</div>
|
<div class="left">仅自己可见</div>
|
||||||
<div class="right" v-if="displayType === enums.DISPLAY_TYPE.ME">
|
<div class="right" v-if="data.displayType === enums.DISPLAY_TYPE.ME">
|
||||||
<img src="../../../assets/img/icon/ok-red.png" alt="" />
|
<img src="../../../assets/img/icon/ok-red.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import enums from '../../../utils/enums'
|
import enums from '../../../utils/enums'
|
||||||
|
|
||||||
export default {
|
import { onMounted, reactive } from 'vue'
|
||||||
name: 'DisplayType',
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
data() {
|
|
||||||
return {
|
defineOptions({
|
||||||
enums,
|
name: 'DisplayType'
|
||||||
displayType: enums.DISPLAY_TYPE.ALL
|
})
|
||||||
}
|
|
||||||
},
|
const router = useRouter()
|
||||||
created() {
|
const route = useRoute()
|
||||||
this.displayType = ~~this.$route.query.displayType
|
const data = reactive({
|
||||||
},
|
displayType: enums.DISPLAY_TYPE.ALL
|
||||||
methods: {
|
})
|
||||||
setDisplayType(type) {
|
|
||||||
this.displayType = type
|
onMounted(() => {
|
||||||
localStorage.setItem('changeDisplayType', type)
|
data.displayType = ~~route.query.displayType
|
||||||
this.$back()
|
})
|
||||||
}
|
|
||||||
}
|
function setDisplayType(type) {
|
||||||
|
data.displayType = type
|
||||||
|
localStorage.setItem('changeDisplayType', type)
|
||||||
|
router.back()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -11,29 +11,29 @@
|
|||||||
<div class="userinfo">
|
<div class="userinfo">
|
||||||
<div class="change-avatar">
|
<div class="change-avatar">
|
||||||
<div class="avatar-ctn" @click="showAvatarDialog">
|
<div class="avatar-ctn" @click="showAvatarDialog">
|
||||||
<img class="avatar" :src="_checkImgUrl(userinfo.cover_url[0].url_list[0])" alt="" />
|
<img class="avatar" :src="_checkImgUrl(store.userinfo.cover_url[0].url_list[0])" alt="" />
|
||||||
<img class="change" src="../../../assets/img/icon/me/camera-light.png" alt="" />
|
<img class="change" src="../../../assets/img/icon/me/camera-light.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
<span>点击更换头像</span>
|
<span>点击更换头像</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="$nav('/me/edit-userinfo-item', { type: 1 })">
|
<div class="row" @click="nav('/me/edit-userinfo-item', { type: 1 })">
|
||||||
<div class="left">名字</div>
|
<div class="left">名字</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>{{ isEmpty(userinfo.nickname) }}</span>
|
<span>{{ isEmpty(store.userinfo.nickname) }}</span>
|
||||||
<dy-back scale=".8" direction="right"></dy-back>
|
<dy-back scale=".8" direction="right"></dy-back>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="$nav('/me/edit-userinfo-item', { type: 2 })">
|
<div class="row" @click="nav('/me/edit-userinfo-item', { type: 2 })">
|
||||||
<div class="left">抖音号</div>
|
<div class="left">抖音号</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>{{ isEmpty(_getUserDouyinId({ author: userinfo })) }}</span>
|
<span>{{ isEmpty(_getUserDouyinId({ author: store.userinfo })) }}</span>
|
||||||
<dy-back scale=".8" direction="right"></dy-back>
|
<dy-back scale=".8" direction="right"></dy-back>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="$nav('/me/edit-userinfo-item', { type: 3 })">
|
<div class="row" @click="nav('/me/edit-userinfo-item', { type: 3 })">
|
||||||
<div class="left">简介</div>
|
<div class="left">简介</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>{{ isEmpty(userinfo.signature) }}</span>
|
<span>{{ isEmpty(store.userinfo.signature) }}</span>
|
||||||
<dy-back scale=".8" direction="right"></dy-back>
|
<dy-back scale=".8" direction="right"></dy-back>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -47,143 +47,143 @@
|
|||||||
<div class="row" @click="showBirthdayDialog">
|
<div class="row" @click="showBirthdayDialog">
|
||||||
<div class="left">生日</div>
|
<div class="left">生日</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>{{ isEmpty(userinfo.user_age) }}</span>
|
<span>{{ isEmpty(store.userinfo.user_age) }}</span>
|
||||||
<div v-show="false" id="trigger1"></div>
|
<div v-show="false" id="trigger1"></div>
|
||||||
<dy-back scale=".8" direction="right"></dy-back>
|
<dy-back scale=".8" direction="right"></dy-back>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="$nav('/me/choose-location')">
|
<div class="row" @click="nav('/me/choose-location')">
|
||||||
<div class="left">所在地</div>
|
<div class="left">所在地</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span v-if="userinfo.province || userinfo.city">
|
<span v-if="store.userinfo.province || store.userinfo.city">
|
||||||
{{ userinfo.province }}
|
{{ store.userinfo.province }}
|
||||||
<template v-if="userinfo.province && userinfo.city"> - </template>
|
<template v-if="store.userinfo.province && store.userinfo.city"> - </template>
|
||||||
{{ userinfo.city }}
|
{{ store.userinfo.city }}
|
||||||
</span>
|
</span>
|
||||||
<dy-back scale=".8" direction="right"></dy-back>
|
<dy-back scale=".8" direction="right"></dy-back>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="$nav('/me/add-school')">
|
<div class="row" @click="nav('/me/add-school')">
|
||||||
<div class="left">学校</div>
|
<div class="left">学校</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>{{ isEmpty(userinfo.school?.name) }}</span>
|
<span>{{ isEmpty(store.userinfo.school?.name) }}</span>
|
||||||
<dy-back scale=".8" direction="right"></dy-back>
|
<dy-back scale=".8" direction="right"></dy-back>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<div class="preview-img" v-if="previewImg" @click="previewImg = ''">
|
<div class="preview-img" v-if="data.previewImg" @click="data.previewImg = ''">
|
||||||
<img class="resource" :src="previewImg" alt="" />
|
<img class="resource" :src="data.previewImg" alt="" />
|
||||||
<img
|
<img
|
||||||
class="download"
|
class="download"
|
||||||
src="../../../assets/img/icon/components/video/download.png"
|
src="../../../assets/img/icon/components/video/download.png"
|
||||||
alt=""
|
alt=""
|
||||||
@click.stop="$no"
|
@click.stop="_no"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import MobileSelect from '../../../components/mobile-select/mobile-select'
|
import MobileSelect from '../../../components/mobile-select/mobile-select'
|
||||||
import { mapState } from 'pinia'
|
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia'
|
||||||
import { _checkImgUrl, _getUserDouyinId } from '../../../utils'
|
import {
|
||||||
|
_checkImgUrl,
|
||||||
|
_getUserDouyinId,
|
||||||
|
_hideLoading,
|
||||||
|
_no,
|
||||||
|
_showLoading,
|
||||||
|
_showSelectDialog,
|
||||||
|
_sleep
|
||||||
|
} from '@/utils'
|
||||||
|
import { computed, reactive } from 'vue'
|
||||||
|
import { useNav } from '@/utils/hooks/useNav'
|
||||||
|
|
||||||
export default {
|
defineOptions({
|
||||||
name: 'EditUserInfo',
|
name: 'EditUserInfo'
|
||||||
setup() {
|
})
|
||||||
const baseStore = useBaseStore()
|
const store = useBaseStore()
|
||||||
return { baseStore }
|
const nav = useNav()
|
||||||
},
|
const data = reactive({
|
||||||
components: {},
|
sexList: [
|
||||||
data() {
|
{ id: 1, name: '男' },
|
||||||
return {
|
{ id: 2, name: '女' },
|
||||||
sexList: [
|
{ id: 3, name: '不展示' }
|
||||||
{ id: 1, name: '男' },
|
],
|
||||||
{ id: 2, name: '女' },
|
avatarList: [
|
||||||
{ id: 3, name: '不展示' }
|
{ id: 1, name: '拍一张' },
|
||||||
],
|
{ id: 2, name: '从相册选择' },
|
||||||
avatarList: [
|
{ id: 3, name: '查看大图' },
|
||||||
{ id: 1, name: '拍一张' },
|
{ id: 4, name: '取消' }
|
||||||
{ id: 2, name: '从相册选择' },
|
],
|
||||||
{ id: 3, name: '查看大图' },
|
previewImg: ''
|
||||||
{ id: 4, name: '取消' }
|
})
|
||||||
],
|
|
||||||
previewImg: ''
|
const sex = computed(() => {
|
||||||
}
|
switch (store.userinfo.gender) {
|
||||||
},
|
case 1:
|
||||||
computed: {
|
return '男'
|
||||||
...mapState(useBaseStore, ['userinfo']),
|
case 2:
|
||||||
sex() {
|
return '女'
|
||||||
switch (this.userinfo.gender) {
|
default:
|
||||||
case 1:
|
return ''
|
||||||
return '男'
|
|
||||||
case 2:
|
|
||||||
return '女'
|
|
||||||
default:
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
_checkImgUrl,
|
|
||||||
_getUserDouyinId,
|
|
||||||
isEmpty(val) {
|
|
||||||
if (val && val !== -1) return val
|
|
||||||
return '点击设置'
|
|
||||||
},
|
|
||||||
showSexDialog() {
|
|
||||||
this.$showSelectDialog(this.sexList, async (e) => {
|
|
||||||
this.$showLoading()
|
|
||||||
await this.$sleep(500)
|
|
||||||
this.baseStore.setUserinfo({ ...this.userinfo, gender: e.id })
|
|
||||||
this.$hideLoading()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
showAvatarDialog() {
|
|
||||||
this.$showSelectDialog(this.avatarList, (e) => {
|
|
||||||
switch (e.id) {
|
|
||||||
case 1:
|
|
||||||
case 2:
|
|
||||||
return this.$no()
|
|
||||||
case 3:
|
|
||||||
this.previewImg = _checkImgUrl(this.userinfo.cover_url[0].url_list[0])
|
|
||||||
break
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
showBirthdayDialog() {
|
|
||||||
new MobileSelect({
|
|
||||||
trigger: '#trigger1',
|
|
||||||
title: '生日',
|
|
||||||
connector: '生日',
|
|
||||||
wheels: [
|
|
||||||
{
|
|
||||||
data: Array.apply(null, { length: 100 }).map((v, i) => new Date().getFullYear() - i)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: Array.apply(null, { length: 12 }).map((v, i) => 12 - i)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
data: Array.apply(null, { length: 31 }).map((v, i) => 31 - i)
|
|
||||||
}
|
|
||||||
],
|
|
||||||
callback: async (indexArr, data) => {
|
|
||||||
console.log(data)
|
|
||||||
this.$showLoading()
|
|
||||||
await this.$sleep(500)
|
|
||||||
this.baseStore.setUserinfo({
|
|
||||||
...this.userinfo,
|
|
||||||
birthday: data.join('-')
|
|
||||||
})
|
|
||||||
this.$hideLoading()
|
|
||||||
// this.localSchool.joinTime = ~~data[0]
|
|
||||||
}
|
|
||||||
}).show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function isEmpty(val) {
|
||||||
|
if (val && val !== -1) return val
|
||||||
|
return '点击设置'
|
||||||
|
}
|
||||||
|
|
||||||
|
function showSexDialog() {
|
||||||
|
_showSelectDialog(data.sexList, async (e) => {
|
||||||
|
_showLoading()
|
||||||
|
await _sleep(500)
|
||||||
|
store.setUserinfo({ ...store.userinfo, gender: e.id })
|
||||||
|
_hideLoading()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function showAvatarDialog() {
|
||||||
|
_showSelectDialog(data.avatarList, (e) => {
|
||||||
|
switch (e.id) {
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
return _no()
|
||||||
|
case 3:
|
||||||
|
data.previewImg = _checkImgUrl(store.userinfo.cover_url[0].url_list[0])
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function showBirthdayDialog() {
|
||||||
|
new MobileSelect({
|
||||||
|
trigger: '#trigger1',
|
||||||
|
title: '生日',
|
||||||
|
connector: '生日',
|
||||||
|
wheels: [
|
||||||
|
{
|
||||||
|
data: Array.apply(null, { length: 100 }).map((v, i) => new Date().getFullYear() - i)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: Array.apply(null, { length: 12 }).map((v, i) => 12 - i)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: Array.apply(null, { length: 31 }).map((v, i) => 31 - i)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
callback: async (indexArr, data) => {
|
||||||
|
_showLoading()
|
||||||
|
await _sleep(500)
|
||||||
|
store.setUserinfo({
|
||||||
|
...store.userinfo,
|
||||||
|
birthday: data.join('-')
|
||||||
|
})
|
||||||
|
_hideLoading()
|
||||||
|
}
|
||||||
|
}).show()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -2,9 +2,9 @@
|
|||||||
<div class="edit-item">
|
<div class="edit-item">
|
||||||
<BaseHeader @back="back">
|
<BaseHeader @back="back">
|
||||||
<template v-slot:center>
|
<template v-slot:center>
|
||||||
<span v-if="type === 1" class="f16">修改名字</span>
|
<span v-if="data.type === 1" class="f16">修改名字</span>
|
||||||
<span v-if="type === 2" class="f16">修改抖音号</span>
|
<span v-if="data.type === 2" class="f16">修改抖音号</span>
|
||||||
<span v-if="type === 3" class="f16">修改简介</span>
|
<span v-if="data.type === 3" class="f16">修改简介</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:right>
|
<template v-slot:right>
|
||||||
<div>
|
<div>
|
||||||
@ -14,37 +14,37 @@
|
|||||||
</BaseHeader>
|
</BaseHeader>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div v-if="type === 1">
|
<div v-if="data.type === 1">
|
||||||
<div class="notice">我的名字</div>
|
<div class="notice">我的名字</div>
|
||||||
<div class="input-ctn" style="margin-bottom: 1rem">
|
<div class="input-ctn" style="margin-bottom: 1rem">
|
||||||
<input type="text" v-model="localUserinfo.nickname" placeholder="记得填写名字哦" />
|
<input type="text" v-model="data.localUserinfo.nickname" placeholder="记得填写名字哦" />
|
||||||
<img
|
<img
|
||||||
v-if="localUserinfo.nickname"
|
v-if="data.localUserinfo.nickname"
|
||||||
style="transform: scale(2)"
|
style="transform: scale(2)"
|
||||||
class="close"
|
class="close"
|
||||||
src="../../../assets/img/icon/newicon/close-and-bg.png"
|
src="../../../assets/img/icon/newicon/close-and-bg.png"
|
||||||
alt=""
|
alt=""
|
||||||
@click="localUserinfo.nickname = ''"
|
@click="data.localUserinfo.nickname = ''"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="num">{{ localUserinfo.nickname.length }}/20</div>
|
<div class="num">{{ data.localUserinfo.nickname.length }}/20</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="l-row" v-if="type === 2">
|
<div class="l-row" v-if="data.type === 2">
|
||||||
<div class="notice">我的抖音号</div>
|
<div class="notice">我的抖音号</div>
|
||||||
<div class="input-ctn" style="margin-bottom: 10rem">
|
<div class="input-ctn" style="margin-bottom: 10rem">
|
||||||
<input type="text" v-model="localUserinfo.unique_id" />
|
<input type="text" v-model="data.localUserinfo.unique_id" />
|
||||||
<img
|
<img
|
||||||
v-if="localUserinfo.unique_id"
|
v-if="data.localUserinfo.unique_id"
|
||||||
style="transform: scale(2)"
|
style="transform: scale(2)"
|
||||||
class="close"
|
class="close"
|
||||||
src="../../../assets/img/icon/newicon/close-and-bg.png"
|
src="../../../assets/img/icon/newicon/close-and-bg.png"
|
||||||
alt=""
|
alt=""
|
||||||
@click="localUserinfo.unique_id = ''"
|
@click="data.localUserinfo.unique_id = ''"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="num">最多16个字,只允许包含字母、数字、下划线和点,30天内仅能修改一次</div>
|
<div class="num">最多16个字,只允许包含字母、数字、下划线和点,30天内仅能修改一次</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="l-row" v-if="type === 3">
|
<div class="l-row" v-if="data.type === 3">
|
||||||
<div class="notice">个人简介</div>
|
<div class="notice">个人简介</div>
|
||||||
<div class="textarea-ctn">
|
<div class="textarea-ctn">
|
||||||
<textarea
|
<textarea
|
||||||
@ -52,7 +52,7 @@
|
|||||||
id=""
|
id=""
|
||||||
cols="30"
|
cols="30"
|
||||||
rows="10"
|
rows="10"
|
||||||
v-model="localUserinfo.signature"
|
v-model="data.localUserinfo.signature"
|
||||||
placeholder="你可以填写兴趣爱好、心情愿望,有趣的介绍能让被关注的概率变高噢!"
|
placeholder="你可以填写兴趣爱好、心情愿望,有趣的介绍能让被关注的概率变高噢!"
|
||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
@ -61,60 +61,68 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
//TODO 1、数据变了后,保存按钮变亮;2、数据变了,点返回,弹窗是否确认
|
//TODO 1、数据变了后,保存按钮变亮;2、数据变了,点返回,弹窗是否确认
|
||||||
|
|
||||||
import { mapState } from 'pinia'
|
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia'
|
||||||
import { cloneDeep } from '@/utils'
|
import {
|
||||||
|
_hideLoading,
|
||||||
|
_notice,
|
||||||
|
_showLoading,
|
||||||
|
_showSimpleConfirmDialog,
|
||||||
|
_sleep,
|
||||||
|
cloneDeep
|
||||||
|
} from '@/utils'
|
||||||
|
import { computed, onMounted, reactive } from 'vue'
|
||||||
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
|
||||||
export default {
|
defineOptions({
|
||||||
name: 'EditUserInfo',
|
name: 'EditUserInfo'
|
||||||
setup() {
|
})
|
||||||
const baseStore = useBaseStore()
|
const store = useBaseStore()
|
||||||
return { baseStore }
|
const router = useRouter()
|
||||||
},
|
const route = useRoute()
|
||||||
data() {
|
const data = reactive({
|
||||||
return {
|
type: 1,
|
||||||
type: 1,
|
localUserinfo: {
|
||||||
localUserinfo: {}
|
nickname: '',
|
||||||
}
|
signature: '',
|
||||||
},
|
unique_id: '',
|
||||||
computed: {
|
desc: ''
|
||||||
isChanged() {
|
|
||||||
if (this.type === 1) if (!this.localUserinfo.nickname) return false
|
|
||||||
if (this.type === 2) if (!this.localUserinfo.desc) return false
|
|
||||||
if (this.userinfo.nickname !== this.localUserinfo.nickname) return true
|
|
||||||
if (this.userinfo.desc !== this.localUserinfo.desc) return true
|
|
||||||
return this.userinfo.unique_id !== this.localUserinfo.unique_id
|
|
||||||
},
|
|
||||||
...mapState(useBaseStore, ['userinfo'])
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.localUserinfo = cloneDeep(this.userinfo)
|
|
||||||
this.type = Number(this.$route.query.type)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
back() {
|
|
||||||
if (this.isChanged) {
|
|
||||||
this.$showSimpleConfirmDialog('是否保存修改', this.save, this.$back)
|
|
||||||
} else {
|
|
||||||
this.$back()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async save() {
|
|
||||||
if (!this.isChanged) return
|
|
||||||
if (this.type === 1) {
|
|
||||||
if (!this.localUserinfo.nickname) return this.$notice('名字不能为空')
|
|
||||||
}
|
|
||||||
this.$showLoading()
|
|
||||||
this.baseStore.setUserinfo(this.localUserinfo)
|
|
||||||
await this.$sleep(500)
|
|
||||||
this.$hideLoading()
|
|
||||||
this.$back()
|
|
||||||
if (this.type === 3) return this.$notice('新签名保存成功')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
const isChanged = computed(() => {
|
||||||
|
if (data.type === 1) if (!data.localUserinfo.nickname) return false
|
||||||
|
if (data.type === 2) if (!data.localUserinfo.desc) return false
|
||||||
|
if (store.userinfo.nickname !== data.localUserinfo.nickname) return true
|
||||||
|
if (store.userinfo.desc !== data.localUserinfo.desc) return true
|
||||||
|
return store.userinfo.unique_id !== data.localUserinfo.unique_id
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
data.localUserinfo = cloneDeep(store.userinfo)
|
||||||
|
data.type = Number(route.query.type)
|
||||||
|
})
|
||||||
|
|
||||||
|
function back() {
|
||||||
|
if (isChanged.value) {
|
||||||
|
_showSimpleConfirmDialog('是否保存修改', save, router.back)
|
||||||
|
} else {
|
||||||
|
router.back()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function save() {
|
||||||
|
if (!isChanged.value) return
|
||||||
|
if (data.type === 1) {
|
||||||
|
if (!data.localUserinfo.nickname) return _notice('名字不能为空')
|
||||||
|
}
|
||||||
|
_showLoading()
|
||||||
|
store.setUserinfo(data.localUserinfo)
|
||||||
|
await _sleep(500)
|
||||||
|
_hideLoading()
|
||||||
|
router.back()
|
||||||
|
if (data.type === 3) return _notice('新签名保存成功')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -2,61 +2,65 @@
|
|||||||
<div id="AllMessage">
|
<div id="AllMessage">
|
||||||
<BaseHeader>
|
<BaseHeader>
|
||||||
<template v-slot:center>
|
<template v-slot:center>
|
||||||
<div class="center" @click="isShowType = !isShowType">
|
<div class="center" @click="data.isShowType = !data.isShowType">
|
||||||
<span class="f16">{{ showTypeText }}</span>
|
<span class="f16">{{ showTypeText }}</span>
|
||||||
<img
|
<img
|
||||||
:class="{ show: isShowType }"
|
:class="{ show: data.isShowType }"
|
||||||
src="../../assets/img/icon/arrow-up-white.png"
|
src="@/assets/img/icon/arrow-up-white.png"
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</BaseHeader>
|
</BaseHeader>
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<div class="type-dialog" v-if="isShowType">
|
<div class="type-dialog" v-if="data.isShowType">
|
||||||
<div class="dialog-content">
|
<div class="dialog-content">
|
||||||
<div class="row" @click="toggleShowType(1)">
|
<div class="row" @click="toggleShowType(1)">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../assets/img/icon/message/done-gray.png" alt="" />
|
<img src="@/assets/img/icon/message/done-gray.png" alt="" />
|
||||||
<span>全部消息</span>
|
<span>全部消息</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="toggleShowType(2)">
|
<div class="row" @click="toggleShowType(2)">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../assets/img/icon/message/like-gray.png" alt="" />
|
<img src="@/assets/img/icon/message/like-gray.png" alt="" />
|
||||||
<span>赞</span>
|
<span>赞</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="toggleShowType(3)">
|
<div class="row" @click="toggleShowType(3)">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../assets/img/icon/message/call-gray.png" alt="" />
|
<img src="@/assets/img/icon/message/call-gray.png" alt="" />
|
||||||
<span>@我的</span>
|
<span>@我的</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" @click="toggleShowType(4)">
|
<div class="row" @click="toggleShowType(4)">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="../../assets/img/icon/message/comment-gray.png" alt="" />
|
<img src="@/assets/img/icon/message/comment-gray.png" alt="" />
|
||||||
<span>评论</span>
|
<span>评论</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mask" @click="isShowType = false"></div>
|
<div class="mask" @click="data.isShowType = false"></div>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<Loading v-if="loading" />
|
<Loading v-if="data.loading" />
|
||||||
<Scroll
|
<Scroll
|
||||||
v-else
|
v-else
|
||||||
ref="mainScroll"
|
ref="mainScroll"
|
||||||
:use-refresh="true"
|
:use-refresh="true"
|
||||||
:loading="loadingMore"
|
:loading="data.loadingMore"
|
||||||
@refresh="refresh"
|
@refresh="refresh"
|
||||||
@pulldown="loadData"
|
@pulldown="loadData"
|
||||||
>
|
>
|
||||||
<div class="messages">
|
<div class="messages">
|
||||||
<div class="message" @click="$nav('/message/visitors')">
|
<div class="message" @click="nav('/message/visitors')">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img v-lazy="_checkImgUrl(userinfo.cover_url[0].url_list[0])" alt="" class="avatar" />
|
<img
|
||||||
|
v-lazy="_checkImgUrl(store.userinfo.cover_url[0].url_list[0])"
|
||||||
|
alt=""
|
||||||
|
class="avatar"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="desc">
|
<div class="desc">
|
||||||
@ -68,27 +72,31 @@
|
|||||||
<div class="time">01-11</div>
|
<div class="time">01-11</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<img v-lazy="_checkImgUrl(userinfo.cover_url[0].url_list[0])" alt="" class="poster" />
|
<img
|
||||||
|
v-lazy="_checkImgUrl(store.userinfo.cover_url[0].url_list[0])"
|
||||||
|
alt=""
|
||||||
|
class="poster"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="message" :key="i" v-for="(item, i) in showMessageList" @click="$no">
|
<div class="message" :key="i" v-for="(item, i) in showMessageList" @click="_no">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img v-lazy="$imgPreview(item.author.avatar)" alt="" class="avatar" />
|
<img v-lazy="_checkImgUrl(item.author.avatar)" alt="" class="avatar" />
|
||||||
<img
|
<img
|
||||||
v-if="selectShowType === 2"
|
v-if="data.selectShowType === 2"
|
||||||
src="../../assets/img/icon/message/love-message.webp"
|
src="@/assets/img/icon/message/love-message.webp"
|
||||||
alt=""
|
alt=""
|
||||||
class="type"
|
class="type"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
v-if="selectShowType === 3"
|
v-if="data.selectShowType === 3"
|
||||||
src="../../assets/img/icon/message/call-message.webp"
|
src="@/assets/img/icon/message/call-message.webp"
|
||||||
alt=""
|
alt=""
|
||||||
class="type"
|
class="type"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
v-if="selectShowType === 4"
|
v-if="data.selectShowType === 4"
|
||||||
src="../../assets/img/icon/message/comment-message.webp"
|
src="@/assets/img/icon/message/comment-message.webp"
|
||||||
alt=""
|
alt=""
|
||||||
class="type"
|
class="type"
|
||||||
/>
|
/>
|
||||||
@ -100,130 +108,130 @@
|
|||||||
<div class="tag">朋友</div>
|
<div class="tag">朋友</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="desc-content">
|
<div class="desc-content">
|
||||||
<span v-if="selectShowType === 1">好好看啊</span>
|
<span v-if="data.selectShowType === 1">好好看啊</span>
|
||||||
<span v-if="selectShowType === 2">赞了你的作品</span>
|
<span v-if="data.selectShowType === 2">赞了你的作品</span>
|
||||||
<span v-if="selectShowType === 3">@{{ userinfo.nickname }}</span>
|
<span v-if="data.selectShowType === 3">@{{ store.userinfo.nickname }}</span>
|
||||||
<span v-if="selectShowType === 4">好好看啊</span>
|
<span v-if="data.selectShowType === 4">好好看啊</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="bottom">
|
<div class="bottom">
|
||||||
<div class="type" v-if="selectShowType === 3">在评论中提到了你</div>
|
<div class="type" v-if="data.selectShowType === 3">在评论中提到了你</div>
|
||||||
<div class="type" v-if="selectShowType === 4">回复了你的评论</div>
|
<div class="type" v-if="data.selectShowType === 4">回复了你的评论</div>
|
||||||
<div class="time">01-11</div>
|
<div class="time">01-11</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<img
|
<img
|
||||||
v-lazy="$imgPreview(item.video + '?vframe/jpg/offset/0/w/300')"
|
v-lazy="_checkImgUrl(item.video + '?vframe/jpg/offset/0/w/300')"
|
||||||
alt=""
|
alt=""
|
||||||
class="poster"
|
class="poster"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="look-all" v-if="!showAll" @click="showAll = true">
|
<div class="look-all" v-if="!data.showAll" @click="data.showAll = true">
|
||||||
<span>查看全部</span>
|
<span>查看全部</span>
|
||||||
<dy-back />
|
<dy-back />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<span>朋友推荐</span>
|
<span>朋友推荐</span>
|
||||||
<img src="../../assets/img/icon/about-gray.png" alt="" />
|
<img src="@/assets/img/icon/about-gray.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
<Peoples v-model:list="recommend" :loading="loadingMore" mode="recommend" />
|
<Peoples v-model:list="data.recommend" :loading="data.loadingMore" mode="recommend" />
|
||||||
</Scroll>
|
</Scroll>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import { mapState } from 'pinia'
|
import Scroll from '@/components/Scroll.vue'
|
||||||
import Scroll from '../../components/Scroll'
|
import Loading from '@/components/Loading.vue'
|
||||||
import Loading from '../../components/Loading'
|
import Peoples from '../people/components/Peoples.vue'
|
||||||
import Peoples from '../people/components/Peoples'
|
import resource from '@/assets/data/resource.js'
|
||||||
import resource from '../../assets/data/resource.js'
|
|
||||||
import BasePage from '../BasePage'
|
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia'
|
||||||
import { _checkImgUrl } from '@/utils'
|
import { _checkImgUrl, _no, _notice, _sleep, cloneDeep } from '@/utils'
|
||||||
|
|
||||||
export default {
|
import { computed, onMounted, reactive } from 'vue'
|
||||||
extends: BasePage,
|
import { useNav } from '@/utils/hooks/useNav.js'
|
||||||
name: 'AllMessage',
|
|
||||||
components: {
|
defineOptions({
|
||||||
Scroll,
|
name: 'AllMessage'
|
||||||
Loading,
|
})
|
||||||
Peoples
|
|
||||||
},
|
const store = useBaseStore()
|
||||||
data() {
|
const nav = useNav()
|
||||||
return {
|
const data = reactive({
|
||||||
loading: false,
|
loading: false,
|
||||||
loadingMore: false,
|
loadingMore: false,
|
||||||
isShowType: false,
|
isShowType: false,
|
||||||
showAll: false,
|
showAll: false,
|
||||||
recommend: [],
|
recommend: [],
|
||||||
messages: [],
|
fans: [],
|
||||||
selectShowType: 1
|
messages: [],
|
||||||
}
|
selectShowType: 1
|
||||||
},
|
})
|
||||||
computed: {
|
|
||||||
...mapState(useBaseStore, ['friends', 'userinfo']),
|
onMounted(() => {
|
||||||
showTypeText() {
|
getData()
|
||||||
switch (this.selectShowType) {
|
})
|
||||||
case 1:
|
|
||||||
return '全部消息'
|
const showTypeText = computed(() => {
|
||||||
case 2:
|
switch (data.selectShowType) {
|
||||||
return '赞'
|
case 1:
|
||||||
case 3:
|
return '全部消息'
|
||||||
return '@我的'
|
case 2:
|
||||||
case 4:
|
return '赞'
|
||||||
return '评论'
|
case 3:
|
||||||
default:
|
return '@我的'
|
||||||
return ''
|
case 4:
|
||||||
}
|
return '评论'
|
||||||
},
|
default:
|
||||||
showMessageList() {
|
return ''
|
||||||
if (this.showAll) {
|
|
||||||
return this.messages
|
|
||||||
}
|
|
||||||
return this.messages.slice(0, 2)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getData()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
_checkImgUrl,
|
|
||||||
async getData() {
|
|
||||||
this.loading = true
|
|
||||||
await this.$sleep(800)
|
|
||||||
this.loading = false
|
|
||||||
this.recommend = this.$clone(this.friends.all)
|
|
||||||
this.fans = this.$clone(this.friends.all)
|
|
||||||
this.recommend.map((v) => {
|
|
||||||
v.type = -1
|
|
||||||
})
|
|
||||||
this.messages = this.$clone(resource.videos)
|
|
||||||
},
|
|
||||||
toggleShowType(index) {
|
|
||||||
this.selectShowType = index
|
|
||||||
this.isShowType = false
|
|
||||||
},
|
|
||||||
remove(index) {
|
|
||||||
this.$notice('将不会再为你推荐该用户')
|
|
||||||
this.recommend.splice(index, 1)
|
|
||||||
},
|
|
||||||
async refresh() {
|
|
||||||
await this.$sleep(1000)
|
|
||||||
this.$refs.mainScroll.refreshEnd()
|
|
||||||
},
|
|
||||||
async loadData() {
|
|
||||||
if (this.loadingMore) return
|
|
||||||
this.loadingMore = true
|
|
||||||
await this.$sleep(500)
|
|
||||||
this.loadingMore = false
|
|
||||||
let temp = this.$clone(this.friends.all)
|
|
||||||
temp.map((v) => {
|
|
||||||
v.type = -1
|
|
||||||
})
|
|
||||||
this.recommend = this.recommend.concat(temp)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const showMessageList = computed(() => {
|
||||||
|
if (data.showAll) {
|
||||||
|
return data.messages
|
||||||
|
}
|
||||||
|
return data.messages.slice(0, 2)
|
||||||
|
})
|
||||||
|
|
||||||
|
async function getData() {
|
||||||
|
data.loading = true
|
||||||
|
await _sleep(800)
|
||||||
|
data.loading = false
|
||||||
|
data.recommend = cloneDeep(store.friends.all)
|
||||||
|
data.fans = cloneDeep(store.friends.all)
|
||||||
|
data.recommend.map((v) => {
|
||||||
|
v.type = -1
|
||||||
|
})
|
||||||
|
data.messages = cloneDeep(resource.videos)
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleShowType(index) {
|
||||||
|
data.selectShowType = index
|
||||||
|
data.isShowType = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// function remove(index) {
|
||||||
|
// _notice('将不会再为你推荐该用户')
|
||||||
|
// data.recommend.splice(index, 1)
|
||||||
|
// }
|
||||||
|
|
||||||
|
async function refresh() {
|
||||||
|
await _sleep(1000)
|
||||||
|
//TODO
|
||||||
|
// data.$refs.mainScroll.refreshEnd()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadData() {
|
||||||
|
if (data.loadingMore) return
|
||||||
|
data.loadingMore = true
|
||||||
|
await _sleep(500)
|
||||||
|
data.loadingMore = false
|
||||||
|
let temp = cloneDeep(store.friends.all)
|
||||||
|
temp.map((v) => {
|
||||||
|
v.type = -1
|
||||||
|
})
|
||||||
|
data.recommend = data.recommend.concat(temp)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -6,8 +6,12 @@
|
|||||||
</template>
|
</template>
|
||||||
<template v-slot:right>
|
<template v-slot:right>
|
||||||
<div>
|
<div>
|
||||||
<span class="f16" :class="selectFriends.length ? 'save-yes' : 'save-no'" @click="save">
|
<span
|
||||||
完成{{ selectFriends.length ? `(${selectFriends.length})` : '' }}
|
class="f16"
|
||||||
|
:class="data.selectFriends.length ? 'save-yes' : 'save-no'"
|
||||||
|
@click="save"
|
||||||
|
>
|
||||||
|
完成{{ data.selectFriends.length ? `(${data.selectFriends.length})` : '' }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -17,11 +21,11 @@
|
|||||||
<div
|
<div
|
||||||
class="local-row"
|
class="local-row"
|
||||||
:key="i"
|
:key="i"
|
||||||
v-for="(item, i) of friends.all"
|
v-for="(item, i) of data.friends.all"
|
||||||
@click="toggleSelect(item)"
|
@click="toggleSelect(item)"
|
||||||
>
|
>
|
||||||
<Check mode="red" v-model="item.select" />
|
<Check mode="red" v-model="item.select" />
|
||||||
<img :src="$imgPreview(item.avatar)" alt="" />
|
<img :src="_checkImgUrl(item.avatar)" alt="" />
|
||||||
<div class="desc">
|
<div class="desc">
|
||||||
<span class="name">{{
|
<span class="name">{{
|
||||||
item.name.length > 20 ? item.name.substr(0, 20) + '...' : item.name
|
item.name.length > 20 ? item.name.substr(0, 20) + '...' : item.name
|
||||||
@ -34,62 +38,63 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import Check from '../../components/Check'
|
import Check from '../../components/Check.vue'
|
||||||
import { friends } from '@/api/user'
|
import { friends } from '@/api/user'
|
||||||
|
|
||||||
export default {
|
import { onMounted, reactive } from 'vue'
|
||||||
name: 'Share2Friend',
|
import { useRouter } from 'vue-router'
|
||||||
components: { Check },
|
import { _checkImgUrl } from '@/utils'
|
||||||
props: {},
|
|
||||||
computed: {
|
defineOptions({
|
||||||
// ...mapState(['friends']),
|
name: 'JoinedGroupChat'
|
||||||
|
})
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const data = reactive({
|
||||||
|
friends: {
|
||||||
|
all: {},
|
||||||
|
recent: [],
|
||||||
|
eachOther: []
|
||||||
},
|
},
|
||||||
data() {
|
selectFriends: []
|
||||||
return {
|
})
|
||||||
friends: {
|
|
||||||
all: {},
|
onMounted(() => {
|
||||||
recent: [],
|
getFriends()
|
||||||
eachOther: []
|
})
|
||||||
},
|
|
||||||
selectFriends: []
|
function save() {
|
||||||
}
|
if (!data.selectFriends.length) return
|
||||||
},
|
router.back()
|
||||||
created() {
|
}
|
||||||
this.getFriends()
|
|
||||||
},
|
function toggleSelect(item) {
|
||||||
methods: {
|
let resIndex = data.selectFriends.findIndex((v) => v.name === item.name)
|
||||||
save() {
|
if (resIndex !== -1) {
|
||||||
if (!this.selectFriends.length) return
|
item.select = false
|
||||||
this.$back()
|
data.selectFriends.splice(resIndex, 1)
|
||||||
},
|
} else {
|
||||||
toggleSelect(item) {
|
item.select = true
|
||||||
let resIndex = this.selectFriends.findIndex((v) => v.name === item.name)
|
data.selectFriends.push(item)
|
||||||
if (resIndex !== -1) {
|
}
|
||||||
item.select = false
|
}
|
||||||
this.selectFriends.splice(resIndex, 1)
|
|
||||||
} else {
|
async function getFriends() {
|
||||||
item.select = true
|
let res = await friends()
|
||||||
this.selectFriends.push(item)
|
if (res.success) {
|
||||||
}
|
data.friends = res.data
|
||||||
},
|
data.friends.all = data.friends.all.sort((a, b) => {
|
||||||
async getFriends() {
|
if (a.pinyin < b.pinyin) return -1
|
||||||
let res = await friends()
|
if (a.pinyin > b.pinyin) return 1
|
||||||
if (res.code === this.SUCCESS) {
|
return 0
|
||||||
this.friends = res.data
|
})
|
||||||
this.friends.all = this.friends.all.sort((a, b) => {
|
|
||||||
if (a.pinyin < b.pinyin) return -1
|
|
||||||
if (a.pinyin > b.pinyin) return 1
|
|
||||||
return 0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
@import '../../assets/less/index';
|
@import '@/assets/less/index';
|
||||||
|
|
||||||
.Share2Friend {
|
.Share2Friend {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|||||||
@ -1,22 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="Message" ref="app" :class="createChatDialog ? 'disable-scroll' : ''">
|
<div id="Message" ref="app" :class="data.createChatDialog ? 'disable-scroll' : ''">
|
||||||
<div class="no-search" v-show="!searching">
|
<div class="no-search" v-show="!data.searching">
|
||||||
<header>
|
<header>
|
||||||
<Icon @click="createChatDialog = true" icon="formkit:add" />
|
<Icon @click="data.createChatDialog = true" icon="formkit:add" />
|
||||||
<Icon icon="tabler:camera-selfie" />
|
<Icon icon="tabler:camera-selfie" />
|
||||||
<Icon @click="searching = true" icon="tabler:search" />
|
<Icon @click="data.searching = true" icon="tabler:search" />
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<Scroll ref="mainScroll">
|
<Scroll ref="mainScroll">
|
||||||
<div class="friends pl1r">
|
<div class="friends pl1r">
|
||||||
<div
|
<div
|
||||||
class="friend pr1r pl1r"
|
class="friend pr1r pl1r"
|
||||||
@click="$nav('/message/chat')"
|
@click="nav('/message/chat')"
|
||||||
:key="index"
|
:key="index"
|
||||||
v-for="(item, index) in friends.all"
|
v-for="(item, index) in store.friends.all"
|
||||||
>
|
>
|
||||||
<div class="avatar" :class="index % 2 === 0 ? 'on-line' : ''">
|
<div class="avatar" :class="index % 2 === 0 ? 'on-line' : ''">
|
||||||
<img :src="$imgPreview(item.avatar)" alt="" />
|
<img :src="_checkImgUrl(item.avatar)" alt="" />
|
||||||
</div>
|
</div>
|
||||||
<span>{{ item.name }}</span>
|
<span>{{ item.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -28,7 +28,7 @@
|
|||||||
<div class="line mt2r"></div>
|
<div class="line mt2r"></div>
|
||||||
<div class="messages">
|
<div class="messages">
|
||||||
<!-- 粉丝-->
|
<!-- 粉丝-->
|
||||||
<div class="message" @click="$nav('/message/fans')">
|
<div class="message" @click="nav('/message/fans')">
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
<img src="../../assets/img/icon/msg-icon1.png" alt="" class="head-image" />
|
<img src="../../assets/img/icon/msg-icon1.png" alt="" class="head-image" />
|
||||||
</div>
|
</div>
|
||||||
@ -45,7 +45,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 互动消息-->
|
<!-- 互动消息-->
|
||||||
<div class="message" @click="$nav('/message/all')">
|
<div class="message" @click="nav('/message/all')">
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
<img src="../../assets/img/icon/msg-icon2.png" alt="" class="head-image" />
|
<img src="../../assets/img/icon/msg-icon2.png" alt="" class="head-image" />
|
||||||
</div>
|
</div>
|
||||||
@ -62,14 +62,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 消息-->
|
<!-- 消息-->
|
||||||
<div class="message" @click="$nav('/message/chat')">
|
<div class="message" @click="nav('/message/chat')">
|
||||||
<div class="avatar on-line">
|
<div class="avatar on-line">
|
||||||
<img src="../../assets/img/icon/avatar/2.png" alt="" class="head-image" />
|
<img src="../../assets/img/icon/avatar/2.png" alt="" class="head-image" />
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<div class="name">
|
<div class="name">
|
||||||
<span>{{ userinfo.nickname }}</span>
|
<span>{{ store.userinfo.nickname }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail">
|
<div class="detail">
|
||||||
哈哈哈哈哈哈
|
哈哈哈哈哈哈
|
||||||
@ -86,7 +86,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 抖音小助手-->
|
<!-- 抖音小助手-->
|
||||||
<div class="message" @click="$nav('/message/douyin-helper')">
|
<div class="message" @click="nav('/message/douyin-helper')">
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
<img src="../../assets/img/icon/msg-icon5.webp" alt="" class="head-image" />
|
<img src="../../assets/img/icon/msg-icon5.webp" alt="" class="head-image" />
|
||||||
</div>
|
</div>
|
||||||
@ -108,7 +108,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 系统通知-->
|
<!-- 系统通知-->
|
||||||
<div class="message" @click="$nav('/message/system-notice')">
|
<div class="message" @click="nav('/message/system-notice')">
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
<img src="../../assets/img/icon/msg-icon4.png" alt="" class="head-image" />
|
<img src="../../assets/img/icon/msg-icon4.png" alt="" class="head-image" />
|
||||||
</div>
|
</div>
|
||||||
@ -130,7 +130,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 求更新-->
|
<!-- 求更新-->
|
||||||
<div class="message" @click="$nav('/me/request-update')">
|
<div class="message" @click="nav('/me/request-update')">
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
<img src="../../assets/img/icon/msg-icon7.webp" alt="" class="head-image" />
|
<img src="../../assets/img/icon/msg-icon7.webp" alt="" class="head-image" />
|
||||||
</div>
|
</div>
|
||||||
@ -152,7 +152,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 任务通知-->
|
<!-- 任务通知-->
|
||||||
<div class="message" @click="$nav('/message/task-notice')">
|
<div class="message" @click="nav('/message/task-notice')">
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
<img src="../../assets/img/icon/msg-icon6.webp" alt="" class="head-image" />
|
<img src="../../assets/img/icon/msg-icon6.webp" alt="" class="head-image" />
|
||||||
</div>
|
</div>
|
||||||
@ -174,7 +174,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 直播通知-->
|
<!-- 直播通知-->
|
||||||
<div class="message" @click="$nav('/message/live-notice')">
|
<div class="message" @click="nav('/message/live-notice')">
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
<img src="../../assets/img/icon/msg-icon8.webp" alt="" class="head-image" />
|
<img src="../../assets/img/icon/msg-icon8.webp" alt="" class="head-image" />
|
||||||
</div>
|
</div>
|
||||||
@ -196,7 +196,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 钱包通知-->
|
<!-- 钱包通知-->
|
||||||
<div class="message" @click="$nav('/message/money-notice')">
|
<div class="message" @click="nav('/message/money-notice')">
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
<img src="../../assets/img/icon/msg-icon9.webp" alt="" class="head-image" />
|
<img src="../../assets/img/icon/msg-icon9.webp" alt="" class="head-image" />
|
||||||
</div>
|
</div>
|
||||||
@ -246,23 +246,23 @@
|
|||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
</div>
|
</div>
|
||||||
</Scroll>
|
</Scroll>
|
||||||
<from-bottom-dialog page-id="Message" v-model="createChatDialog">
|
<from-bottom-dialog page-id="Message" v-model="data.createChatDialog">
|
||||||
<div class="create-chat-wrapper" v-show="!showJoinedChat">
|
<div class="create-chat-wrapper" v-show="!data.showJoinedChat">
|
||||||
<Search
|
<Search
|
||||||
:isShowRightText="isShowRightText"
|
:isShowRightText="data.isShowRightText"
|
||||||
@click="isShowRightText = true"
|
@click="data.isShowRightText = true"
|
||||||
@notice="isShowRightText = false"
|
@notice="data.isShowRightText = false"
|
||||||
@clear="isShowRightText = false"
|
@clear="data.isShowRightText = false"
|
||||||
class="ml2r mr2r"
|
class="ml2r mr2r"
|
||||||
placeholder="搜索用户"
|
placeholder="搜索用户"
|
||||||
v-model="createChatSearchKey"
|
v-model="data.createChatSearchKey"
|
||||||
></Search>
|
></Search>
|
||||||
<template v-if="createChatSearchKey">
|
<template v-if="data.createChatSearchKey">
|
||||||
<div class="search-result" v-if="searchFriends.length">
|
<div class="search-result" v-if="data.searchFriends.length">
|
||||||
<div
|
<div
|
||||||
class="search-result-item"
|
class="search-result-item"
|
||||||
:key="i"
|
:key="i"
|
||||||
v-for="(item, i) in searchFriends"
|
v-for="(item, i) in data.searchFriends"
|
||||||
@click="handleClick(item)"
|
@click="handleClick(item)"
|
||||||
>
|
>
|
||||||
<img class="left" src="../../assets/img/icon/head-image.jpeg" alt="" />
|
<img class="left" src="../../assets/img/icon/head-image.jpeg" alt="" />
|
||||||
@ -286,7 +286,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="joined-chat" @click="showJoinedChat = true">
|
<div class="joined-chat" @click="data.showJoinedChat = true">
|
||||||
<img class="left" src="../../assets/img/icon/people-gray.png" alt="" />
|
<img class="left" src="../../assets/img/icon/people-gray.png" alt="" />
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>已加入的群聊</span>
|
<span>已加入的群聊</span>
|
||||||
@ -298,10 +298,10 @@
|
|||||||
<div
|
<div
|
||||||
class="friend-item"
|
class="friend-item"
|
||||||
:key="i"
|
:key="i"
|
||||||
v-for="(item, i) in friends.all"
|
v-for="(item, i) in store.friends.all"
|
||||||
@click="item.select = !item.select"
|
@click="item.select = !item.select"
|
||||||
>
|
>
|
||||||
<img class="left" :src="$imgPreview(item.avatar)" alt="" />
|
<img class="left" :src="_checkImgUrl(item.avatar)" alt="" />
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>{{ item.name }}</span>
|
<span>{{ item.name }}</span>
|
||||||
<Check mode="red" style="height: 20rem; width: 20rem" v-model="item.select" />
|
<Check mode="red" style="height: 20rem; width: 20rem" v-model="item.select" />
|
||||||
@ -313,9 +313,9 @@
|
|||||||
<div class="btn" :class="selectFriends ? 'primary' : ''">发起聊天</div>
|
<div class="btn" :class="selectFriends ? 'primary' : ''">发起聊天</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="joined-chat-wrapper" v-show="showJoinedChat">
|
<div class="joined-chat-wrapper" v-show="data.showJoinedChat">
|
||||||
<div class="nav">
|
<div class="nav">
|
||||||
<dy-back @click="showJoinedChat = false" mode="light" scale="1.2"></dy-back>
|
<dy-back @click="data.showJoinedChat = false" mode="light" scale="1.2"></dy-back>
|
||||||
<span>已加入的群聊</span>
|
<span>已加入的群聊</span>
|
||||||
<span> </span>
|
<span> </span>
|
||||||
</div>
|
</div>
|
||||||
@ -326,7 +326,7 @@
|
|||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<div class="name">
|
<div class="name">
|
||||||
{{ text.length > 20 ? text.substr(0, 20) + '...' : text }}
|
{{ data.text.length > 20 ? data.text.substr(0, 20) + '...' : data.text }}
|
||||||
</div>
|
</div>
|
||||||
<div class="num">(3)</div>
|
<div class="num">(3)</div>
|
||||||
</div>
|
</div>
|
||||||
@ -339,7 +339,7 @@
|
|||||||
</from-bottom-dialog>
|
</from-bottom-dialog>
|
||||||
|
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<div class="recommend-dialog" v-if="isShowRecommend">
|
<div class="recommend-dialog" v-if="data.isShowRecommend">
|
||||||
<div class="dialog-content">
|
<div class="dialog-content">
|
||||||
<div class="dialog-header">
|
<div class="dialog-header">
|
||||||
<img
|
<img
|
||||||
@ -352,15 +352,15 @@
|
|||||||
<img src="../../assets/img/icon/about-gray.png" alt="" />
|
<img src="../../assets/img/icon/about-gray.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
<img
|
<img
|
||||||
@click="isShowRecommend = false"
|
@click="data.isShowRecommend = false"
|
||||||
src="../../assets/img/icon/components/gray-close-full2.png"
|
src="../../assets/img/icon/components/gray-close-full2.png"
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-body">
|
<div class="dialog-body">
|
||||||
<Scroll ref="scroll" @pulldown="loadRecommendData">
|
<Scroll ref="scroll" @pulldown="loadRecommendData">
|
||||||
<Peoples v-model:list="recommend" :loading="loading" mode="recommend" />
|
<Peoples v-model:list="data.recommend" :loading="data.loading" mode="recommend" />
|
||||||
<Loading :is-full-screen="false" v-if="loading" />
|
<Loading :is-full-screen="false" v-if="data.loading" />
|
||||||
<NoMore v-else />
|
<NoMore v-else />
|
||||||
</Scroll>
|
</Scroll>
|
||||||
</div>
|
</div>
|
||||||
@ -371,22 +371,22 @@
|
|||||||
<BaseFooter v-bind:init-tab="4" />
|
<BaseFooter v-bind:init-tab="4" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="searching" v-show="searching">
|
<div class="searching" v-show="data.searching">
|
||||||
<Search
|
<Search
|
||||||
v-model="searchKey"
|
v-model="data.searchKey"
|
||||||
right-text="取消"
|
right-text="取消"
|
||||||
right-text-color="white"
|
right-text-color="white"
|
||||||
@notice="searching = false"
|
@notice="data.searching = false"
|
||||||
:isShowRightText="true"
|
:isShowRightText="true"
|
||||||
/>
|
/>
|
||||||
<div class="more-chat">
|
<div class="more-chat">
|
||||||
<template v-if="searchKey">
|
<template v-if="data.searchKey">
|
||||||
<div class="sub-title" v-if="searchFriendsAll.length">
|
<div class="sub-title" v-if="searchFriendsAll.length">
|
||||||
<span>联系人</span>
|
<span>联系人</span>
|
||||||
<div
|
<div
|
||||||
class="right"
|
class="right"
|
||||||
v-if="searchFriendsAll.length > 3"
|
v-if="searchFriendsAll.length > 3"
|
||||||
@click="$nav('/message/more-search', { key: searchKey })"
|
@click="nav('/message/more-search', { key: data.searchKey })"
|
||||||
>
|
>
|
||||||
<span>更多联系人</span>
|
<span>更多联系人</span>
|
||||||
<dy-back mode="gray" img="back" scale=".6" direction="right" />
|
<dy-back mode="gray" img="back" scale=".6" direction="right" />
|
||||||
@ -396,15 +396,15 @@
|
|||||||
v-for="item in searchFriendsAll.slice(0, 3)"
|
v-for="item in searchFriendsAll.slice(0, 3)"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
mode="search"
|
mode="search"
|
||||||
:searchKey="searchKey"
|
:searchKey="data.searchKey"
|
||||||
:people="item"
|
:people="item"
|
||||||
/>
|
/>
|
||||||
<div class="goto-search-page" @click="$nav('/home/search', { key: searchKey })">
|
<div class="goto-search-page" @click="nav('/home/search', { key: data.searchKey })">
|
||||||
<img class="icon" src="../../assets/img/icon/search-light.png" alt="" />
|
<img class="icon" src="../../assets/img/icon/search-light.png" alt="" />
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<span
|
<span
|
||||||
>搜索 <span style="color: yellow">{{ searchKey }}</span></span
|
>搜索 <span style="color: yellow">{{ data.searchKey }}</span></span
|
||||||
>
|
>
|
||||||
<span class="second-text-color f12">视频、用户、音乐、话题、地点等</span>
|
<span class="second-text-color f12">视频、用户、音乐、话题、地点等</span>
|
||||||
</div>
|
</div>
|
||||||
@ -414,105 +414,96 @@
|
|||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="sub-title">更多聊天</div>
|
<div class="sub-title">更多聊天</div>
|
||||||
<People v-for="item in moreChat" :key="item.id" :people="item" />
|
<People v-for="item in data.moreChat" :key="item.id" :people="item" />
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import Search from '../../components/Search'
|
import Search from '../../components/Search.vue'
|
||||||
import FromBottomDialog from '../../components/dialog/FromBottomDialog'
|
import FromBottomDialog from '../../components/dialog/FromBottomDialog.vue'
|
||||||
import Check from '../../components/Check'
|
import Check from '../../components/Check.vue'
|
||||||
import { mapState } from 'pinia'
|
import Peoples from '../people/components/Peoples.vue'
|
||||||
import Peoples from '../people/components/Peoples'
|
import People from '../people/components/Peoples.vue'
|
||||||
import Scroll from '../../components/Scroll'
|
import Scroll from '../../components/Scroll.vue'
|
||||||
import People from '../people/components/People'
|
|
||||||
import BasePage from '../BasePage'
|
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia'
|
||||||
|
|
||||||
export default {
|
import { computed, onMounted, reactive, watch } from 'vue'
|
||||||
extends: BasePage,
|
import { useNav } from '@/utils/hooks/useNav.js'
|
||||||
name: 'Message',
|
import { _checkImgUrl, _sleep, cloneDeep } from '@/utils'
|
||||||
components: {
|
|
||||||
Scroll,
|
defineOptions({
|
||||||
Search,
|
name: 'Message'
|
||||||
FromBottomDialog,
|
})
|
||||||
Check,
|
|
||||||
Peoples,
|
const store = useBaseStore()
|
||||||
People
|
const nav = useNav()
|
||||||
},
|
const data = reactive({
|
||||||
data() {
|
isShowRecommend: false,
|
||||||
return {
|
searching: false,
|
||||||
isShowRecommend: false,
|
searchKey: '',
|
||||||
searching: false,
|
createChatSearchKey: '',
|
||||||
searchKey: '',
|
showJoinedChat: false,
|
||||||
createChatSearchKey: '',
|
loading: false,
|
||||||
showJoinedChat: false,
|
createChatDialog: false,
|
||||||
loading: false,
|
isShowRightText: false,
|
||||||
createChatDialog: false,
|
text: 'AAAAAAAAA、BBBBBBBBBBBBB、CCCCCCCC',
|
||||||
isShowRightText: false,
|
searchFriends: [],
|
||||||
text: 'AAAAAAAAA、BBBBBBBBBBBBB、CCCCCCCC',
|
recommend: [],
|
||||||
searchFriends: [],
|
moreChat: []
|
||||||
recommend: [],
|
})
|
||||||
moreChat: []
|
|
||||||
}
|
onMounted(() => {
|
||||||
},
|
console.log('create')
|
||||||
computed: {
|
data.recommend = cloneDeep(store.friends.all)
|
||||||
...mapState(useBaseStore, ['friends', 'userinfo']),
|
data.recommend.map((v) => {
|
||||||
selectFriends() {
|
v.type = -2
|
||||||
return this.friends.all.filter((v) => v.select).length
|
})
|
||||||
},
|
data.moreChat = cloneDeep(store.friends.all.slice(0, 3))
|
||||||
searchFriendsAll() {
|
})
|
||||||
return this.friends.all.filter((v) => {
|
|
||||||
return v.name.search(this.searchKey) !== -1 || v.account.search(this.searchKey) !== -1
|
const selectFriends = computed(() => {
|
||||||
|
return store.friends.all.filter((v) => v.select).length
|
||||||
|
})
|
||||||
|
|
||||||
|
const searchFriendsAll = computed(() => {
|
||||||
|
return store.friends.all.filter((v) => {
|
||||||
|
return v.name.search(data.searchKey) !== -1 || v.account.search(data.searchKey) !== -1
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => data.createChatSearchKey,
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
//TODO 搜索时仅仅判断是否包含了对应字符串,抖音做了拼音判断的
|
||||||
|
data.searchFriends = store.friends.all.filter((v) => {
|
||||||
|
if (v.name.includes(newVal)) return true
|
||||||
|
return v.account.includes(newVal)
|
||||||
})
|
})
|
||||||
}
|
} else {
|
||||||
},
|
data.searchFriends = []
|
||||||
watch: {
|
|
||||||
createChatSearchKey(newVal) {
|
|
||||||
if (newVal) {
|
|
||||||
//TODO 搜索时仅仅判断是否包含了对应字符串,抖音做了拼音判断的
|
|
||||||
this.searchFriends = this.friends.all.filter((v) => {
|
|
||||||
if (v.name.includes(newVal)) return true
|
|
||||||
return v.account.includes(newVal)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.searchFriends = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
console.log('create')
|
|
||||||
this.recommend = this.$clone(this.friends.all)
|
|
||||||
this.recommend.map((v) => {
|
|
||||||
v.type = -2
|
|
||||||
})
|
|
||||||
this.moreChat = this.$clone(this.friends.all.slice(0, 3))
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
setTimeout(() => {
|
|
||||||
// this.isShowRecommend = true
|
|
||||||
}, 1000)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleClick(item) {
|
|
||||||
item.select = !item.select
|
|
||||||
this.createChatSearchKey = ''
|
|
||||||
},
|
|
||||||
async loadRecommendData() {
|
|
||||||
if (this.loading) return
|
|
||||||
this.loading = true
|
|
||||||
await this.$sleep(500)
|
|
||||||
this.loading = false
|
|
||||||
let temp = this.$clone(this.friends.all)
|
|
||||||
temp.map((v) => {
|
|
||||||
v.type = -2
|
|
||||||
})
|
|
||||||
this.recommend = this.recommend.concat(temp)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
function handleClick(item) {
|
||||||
|
item.select = !item.select
|
||||||
|
data.createChatSearchKey = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadRecommendData() {
|
||||||
|
if (data.loading) return
|
||||||
|
data.loading = true
|
||||||
|
await _sleep(500)
|
||||||
|
data.loading = false
|
||||||
|
let temp = cloneDeep(store.friends.all)
|
||||||
|
temp.map((v) => {
|
||||||
|
v.type = -2
|
||||||
|
})
|
||||||
|
data.recommend = data.recommend.concat(temp)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
|||||||
@ -2,53 +2,50 @@
|
|||||||
<div id="MoreSearch">
|
<div id="MoreSearch">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<Search
|
<Search
|
||||||
v-model="searchKey"
|
v-model="data.searchKey"
|
||||||
right-text="取消"
|
right-text="取消"
|
||||||
right-text-color="white"
|
right-text-color="white"
|
||||||
@notice="$back"
|
@notice="router.back"
|
||||||
:isShowRightText="true"
|
:isShowRightText="true"
|
||||||
/>
|
/>
|
||||||
<People
|
<People
|
||||||
v-for="item in searchFriendsAll"
|
v-for="item in searchFriendsAll"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
mode="search"
|
mode="search"
|
||||||
:searchKey="searchKey"
|
:searchKey="data.searchKey"
|
||||||
:people="item"
|
:people="item"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import Search from '../../components/Search'
|
import Search from '@/components/Search.vue'
|
||||||
import { mapState } from 'pinia'
|
import People from '../people/components/Peoples.vue'
|
||||||
import People from '../people/components/People'
|
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia'
|
||||||
|
|
||||||
export default {
|
import { computed, onMounted, reactive } from 'vue'
|
||||||
name: 'MoreSearch',
|
import { useNav } from '@/utils/hooks/useNav.js'
|
||||||
components: {
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
Search,
|
|
||||||
People
|
defineOptions({
|
||||||
},
|
name: 'MoreSearch'
|
||||||
data() {
|
})
|
||||||
return {
|
|
||||||
searchKey: ''
|
const store = useBaseStore()
|
||||||
}
|
const router = useRouter()
|
||||||
},
|
const route = useRoute()
|
||||||
computed: {
|
const data = reactive({
|
||||||
...mapState(useBaseStore, ['friends', 'userinfo']),
|
searchKey: ''
|
||||||
searchFriendsAll() {
|
})
|
||||||
return this.friends.all.filter((v) => {
|
|
||||||
return v.name.search(this.searchKey) !== -1 || v.account.search(this.searchKey) !== -1
|
const searchFriendsAll = computed(() => {
|
||||||
})
|
return store.friends.all.filter((v) => {
|
||||||
}
|
return v.name.search(data.searchKey) !== -1 || v.account.search(data.searchKey) !== -1
|
||||||
},
|
})
|
||||||
watch: {},
|
})
|
||||||
created() {
|
onMounted(() => {
|
||||||
this.searchKey = this.$route.query.key
|
data.searchKey = String(route.query.key)
|
||||||
},
|
})
|
||||||
methods: {}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
|||||||
@ -5,12 +5,12 @@
|
|||||||
<span class="f16">主页访客</span>
|
<span class="f16">主页访客</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:right>
|
<template v-slot:right>
|
||||||
<span class="f14" @click="isShowSetting = !isShowSetting">设置</span>
|
<span class="f14" @click="data.isShowSetting = !data.isShowSetting">设置</span>
|
||||||
</template>
|
</template>
|
||||||
</BaseHeader>
|
</BaseHeader>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<template v-if="realDisplay">
|
<template v-if="data.realDisplay">
|
||||||
<Peoples v-model:list="recommend" :loading="loading" mode="visitor" />
|
<Peoples v-model:list="data.recommend" :loading="false" mode="visitor" />
|
||||||
<NoMore />
|
<NoMore />
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
@ -18,7 +18,11 @@
|
|||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<img src="../../assets/img/icon/message/display2.webp" alt="" class="icon1" />
|
<img src="../../assets/img/icon/message/display2.webp" alt="" class="icon1" />
|
||||||
<img :src="_checkImgUrl(userinfo.cover_url[0].url_list[0])" alt="" class="icon2" />
|
<img
|
||||||
|
:src="_checkImgUrl(store.userinfo.cover_url[0].url_list[0])"
|
||||||
|
alt=""
|
||||||
|
class="icon2"
|
||||||
|
/>
|
||||||
<img src="../../assets/img/icon/message/display1.webp" alt="" class="icon3" />
|
<img src="../../assets/img/icon/message/display1.webp" alt="" class="icon3" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -31,7 +35,9 @@
|
|||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<base-button type="dark" @click="keepClose">保持关闭</base-button>
|
<base-button type="dark" @click="keepClose">保持关闭</base-button>
|
||||||
<base-button type="primary" @click="display = realDisplay = true">开启访客</base-button>
|
<base-button type="primary" @click="data.display = data.realDisplay = true"
|
||||||
|
>开启访客</base-button
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -39,7 +45,7 @@
|
|||||||
|
|
||||||
<from-bottom-dialog
|
<from-bottom-dialog
|
||||||
page-id="Visitors"
|
page-id="Visitors"
|
||||||
v-model="isShowSetting"
|
v-model="data.isShowSetting"
|
||||||
mode="white"
|
mode="white"
|
||||||
mask-mode="dark"
|
mask-mode="dark"
|
||||||
height="270rem"
|
height="270rem"
|
||||||
@ -51,7 +57,7 @@
|
|||||||
<img class="icon" src="../../assets/img/icon/message/peoples-black2.png" alt="" />
|
<img class="icon" src="../../assets/img/icon/message/peoples-black2.png" alt="" />
|
||||||
<transition name="remove">
|
<transition name="remove">
|
||||||
<img
|
<img
|
||||||
v-if="!display"
|
v-if="!data.display"
|
||||||
class="remove"
|
class="remove"
|
||||||
src="../../assets/img/icon/message/remove.png"
|
src="../../assets/img/icon/message/remove.png"
|
||||||
alt=""
|
alt=""
|
||||||
@ -60,7 +66,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<img
|
<img
|
||||||
class="close"
|
class="close"
|
||||||
@click="isShowSetting = false"
|
@click="data.isShowSetting = false"
|
||||||
src="../../assets/img/icon/components/gray-close-full2.png"
|
src="../../assets/img/icon/components/gray-close-full2.png"
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
@ -73,60 +79,54 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="left">展示主页访客</div>
|
<div class="left">展示主页访客</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<switches v-model="display" theme="bootstrap" color="success"></switches>
|
<switches v-model="data.display" theme="bootstrap" color="success"></switches>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</from-bottom-dialog>
|
</from-bottom-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import { mapState } from 'pinia'
|
import Peoples from '../people/components/Peoples.vue'
|
||||||
import Peoples from '../people/components/Peoples'
|
import NoMore from '@/components/NoMore.vue'
|
||||||
import NoMore from '../../components/NoMore'
|
import FromBottomDialog from '@/components/dialog/FromBottomDialog.vue'
|
||||||
import FromBottomDialog from '../../components/dialog/FromBottomDialog'
|
import Switches from './components/swtich/switches.vue'
|
||||||
import Switches from './components/swtich/switches'
|
import BaseButton from '@/components/BaseButton.vue'
|
||||||
import BaseButton from '../../components/BaseButton'
|
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia'
|
||||||
import { _checkImgUrl } from '@/utils'
|
import { _checkImgUrl, _notice, cloneDeep } from '@/utils'
|
||||||
|
|
||||||
export default {
|
import { onMounted, reactive, watch } from 'vue'
|
||||||
name: 'visitors',
|
import { useRouter } from 'vue-router'
|
||||||
components: {
|
|
||||||
BaseButton,
|
defineOptions({
|
||||||
FromBottomDialog,
|
name: 'Visitors'
|
||||||
Peoples,
|
})
|
||||||
NoMore,
|
|
||||||
Switches
|
const store = useBaseStore()
|
||||||
},
|
const router = useRouter()
|
||||||
data() {
|
const data = reactive({
|
||||||
return {
|
recommend: [],
|
||||||
recommend: [],
|
isShowSetting: false,
|
||||||
isShowSetting: false,
|
display: false,
|
||||||
display: false,
|
realDisplay: false
|
||||||
realDisplay: false
|
})
|
||||||
}
|
|
||||||
},
|
onMounted(() => {
|
||||||
watch: {
|
data.recommend = cloneDeep(store.friends.all)
|
||||||
isShowSetting(newVal) {
|
})
|
||||||
if (!newVal) {
|
|
||||||
this.realDisplay = this.display
|
watch(
|
||||||
}
|
() => data.isShowSetting,
|
||||||
}
|
(newVal) => {
|
||||||
},
|
if (!newVal) {
|
||||||
computed: {
|
data.realDisplay = data.display
|
||||||
...mapState(useBaseStore, ['friends', 'userinfo'])
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.recommend = this.$clone(this.friends.all)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
_checkImgUrl,
|
|
||||||
keepClose() {
|
|
||||||
this.$notice('你将不会再收到相关通知')
|
|
||||||
this.$back()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
function keepClose() {
|
||||||
|
_notice('你将不会再收到相关通知')
|
||||||
|
router.back()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -184,6 +184,7 @@ export default {
|
|||||||
background: black;
|
background: black;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
width: 80rem;
|
width: 80rem;
|
||||||
|
height: 80rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon3 {
|
.icon3 {
|
||||||
|
|||||||
@ -5,13 +5,13 @@
|
|||||||
<span class="f16">抖音小助手</span>
|
<span class="f16">抖音小助手</span>
|
||||||
</template>
|
</template>
|
||||||
</BaseHeader>
|
</BaseHeader>
|
||||||
<Loading v-if="loading" />
|
<Loading v-if="data.loading" />
|
||||||
<Scroll v-else ref="mainScroll">
|
<Scroll v-else ref="mainScroll">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<NoMore />
|
<NoMore />
|
||||||
<div class="list">
|
<div class="list">
|
||||||
<!--TODO 超过3行显示全文-->
|
<!--TODO 超过3行显示全文-->
|
||||||
<div class="item" :key="i" v-for="(item, i) in list" @click="goDetail(item)">
|
<div class="item" :key="i" v-for="(item, i) in data.list" @click="goDetail(item)">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{ item.title }}
|
{{ item.title }}
|
||||||
<div class="ml1r not-read" v-if="!item.read"></div>
|
<div class="ml1r not-read" v-if="!item.read"></div>
|
||||||
@ -28,82 +28,78 @@
|
|||||||
</Scroll>
|
</Scroll>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import { nextTick } from 'vue'
|
import { nextTick, onMounted, reactive } from 'vue'
|
||||||
import Scroll from '../../../components/Scroll'
|
import Scroll from '@/components/Scroll.vue'
|
||||||
import BasePage from '../../BasePage'
|
import { _no, _sleep } from '@/utils'
|
||||||
|
|
||||||
export default {
|
defineOptions({
|
||||||
extends: BasePage,
|
name: 'DouyinHelper'
|
||||||
name: 'DouyinHelper',
|
})
|
||||||
components: { Scroll },
|
|
||||||
data() {
|
const data = reactive({
|
||||||
return {
|
loading: false,
|
||||||
loading: false,
|
list: [
|
||||||
list: [
|
{
|
||||||
{
|
read: false,
|
||||||
read: false,
|
title: '叮!你有一条《长津湖》观看提醒',
|
||||||
title: '叮!你有一条《长津湖》观看提醒',
|
time: '2021-10-12 12:12',
|
||||||
time: '2021-10-12 12:12',
|
content:
|
||||||
content:
|
'领跑国庆档,吴京、易烊千玺“京玺”兄弟共赴战场!燃爽炸裂的视觉冲击,义勇前行的坚定信念,尽在长津湖“意志之战”。点击查看详情,戳我优惠看>>'
|
||||||
'领跑国庆档,吴京、易烊千玺“京玺”兄弟共赴战场!燃爽炸裂的视觉冲击,义勇前行的坚定信念,尽在长津湖“意志之战”。点击查看详情,戳我优惠看>>'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
read: false,
|
|
||||||
title: '国庆打卡美好中国',
|
|
||||||
time: '2021-10-12 12:12',
|
|
||||||
content:
|
|
||||||
'山河千年,风景依旧,一幅幅大美的城市山水画在国庆舞台中徐徐展开。点击[查看详情]在拼音打卡美好中国,领跑不同城市的韵味,最高还能赢10000元旅行红包哦!'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
read: false,
|
|
||||||
title: '#今天谁请客呢',
|
|
||||||
time: '2021-10-12 12:12',
|
|
||||||
content:
|
|
||||||
'你还在为朋友吃饭谁请客发愁吗?快邀请朋友一起来参加花式甩单挑战,今日消费,淘特请客!还不快来拍摄互动视频?现金大奖等你来分!'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
read: false,
|
|
||||||
title: '#寻找武林第一人',
|
|
||||||
time: '2021-10-12 12:12',
|
|
||||||
content:
|
|
||||||
'《天涯明月刀手游》在线悬赏“武林第一人”。10月10日-10月19日内,参与挑战,生成你的专属卡面,测一测你的武林专属称号吧!天刀手游周年庆也在火热进行中,全民福利等你拿! [本活动与Apple Inc.无关]'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
read: false,
|
|
||||||
title: '谁是偷偷爱你的人',
|
|
||||||
time: '2021-10-12 12:12',
|
|
||||||
content:
|
|
||||||
'想知道怎么跟TA们走的更近吗?10月11日-10月16日正好有一个合适的机会,赶紧点击了解详情>>'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
read: false,
|
|
||||||
title: '看美好奇妙夜,赢万元红包!',
|
|
||||||
time: '2021-10-12 12:12',
|
|
||||||
content:
|
|
||||||
'今天晚上8点,2021抖音美好奇妙夜直播开启!30多位艺人、100多位创作者齐聚一堂,为你带来全方位的视听盛宴,观看直播更有机会赢万元红包大奖,更多精彩,不容错过!快来直接间看看吧! [本活动与Apple Inc.无关]'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {},
|
|
||||||
created() {
|
|
||||||
this.getData()
|
|
||||||
},
|
|
||||||
mounted() {},
|
|
||||||
methods: {
|
|
||||||
async getData() {
|
|
||||||
this.loading = true
|
|
||||||
await this.$sleep(700)
|
|
||||||
this.loading = false
|
|
||||||
await nextTick()
|
|
||||||
this.$refs.mainScroll.scrollBottom()
|
|
||||||
},
|
},
|
||||||
goDetail(item) {
|
{
|
||||||
item.read = true
|
read: false,
|
||||||
this.$no()
|
title: '国庆打卡美好中国',
|
||||||
|
time: '2021-10-12 12:12',
|
||||||
|
content:
|
||||||
|
'山河千年,风景依旧,一幅幅大美的城市山水画在国庆舞台中徐徐展开。点击[查看详情]在拼音打卡美好中国,领跑不同城市的韵味,最高还能赢10000元旅行红包哦!'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
read: false,
|
||||||
|
title: '#今天谁请客呢',
|
||||||
|
time: '2021-10-12 12:12',
|
||||||
|
content:
|
||||||
|
'你还在为朋友吃饭谁请客发愁吗?快邀请朋友一起来参加花式甩单挑战,今日消费,淘特请客!还不快来拍摄互动视频?现金大奖等你来分!'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
read: false,
|
||||||
|
title: '#寻找武林第一人',
|
||||||
|
time: '2021-10-12 12:12',
|
||||||
|
content:
|
||||||
|
'《天涯明月刀手游》在线悬赏“武林第一人”。10月10日-10月19日内,参与挑战,生成你的专属卡面,测一测你的武林专属称号吧!天刀手游周年庆也在火热进行中,全民福利等你拿! [本活动与Apple Inc.无关]'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
read: false,
|
||||||
|
title: '谁是偷偷爱你的人',
|
||||||
|
time: '2021-10-12 12:12',
|
||||||
|
content:
|
||||||
|
'想知道怎么跟TA们走的更近吗?10月11日-10月16日正好有一个合适的机会,赶紧点击了解详情>>'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
read: false,
|
||||||
|
title: '看美好奇妙夜,赢万元红包!',
|
||||||
|
time: '2021-10-12 12:12',
|
||||||
|
content:
|
||||||
|
'今天晚上8点,2021抖音美好奇妙夜直播开启!30多位艺人、100多位创作者齐聚一堂,为你带来全方位的视听盛宴,观看直播更有机会赢万元红包大奖,更多精彩,不容错过!快来直接间看看吧! [本活动与Apple Inc.无关]'
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getData()
|
||||||
|
})
|
||||||
|
|
||||||
|
async function getData() {
|
||||||
|
data.loading = true
|
||||||
|
await _sleep(700)
|
||||||
|
data.loading = false
|
||||||
|
await nextTick()
|
||||||
|
// data.$refs.mainScroll.scrollBottom()
|
||||||
|
}
|
||||||
|
|
||||||
|
function goDetail(item) {
|
||||||
|
item.read = true
|
||||||
|
_no()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -5,18 +5,18 @@
|
|||||||
<span class="f16">系统通知</span>
|
<span class="f16">系统通知</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:right>
|
<template v-slot:right>
|
||||||
<span class="f14" @click="$nav('/message/notice-setting', { type: 'SYSTEM' })"
|
<span class="f14" @click="nav('/message/notice-setting', { type: 'SYSTEM' })"
|
||||||
>通知设置</span
|
>通知设置</span
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
</BaseHeader>
|
</BaseHeader>
|
||||||
<Loading v-if="loading" />
|
<Loading v-if="data.loading" />
|
||||||
<div class="content" v-else>
|
<div class="content" v-else>
|
||||||
<Scroll ref="mainScroll">
|
<Scroll ref="mainScroll">
|
||||||
<div class="list">
|
<div class="list">
|
||||||
<NoMore />
|
<NoMore />
|
||||||
<!--TODO 超过3行显示全文-->
|
<!--TODO 超过3行显示全文-->
|
||||||
<div class="item" :key="i" v-for="(item, i) in list" @click="goDetail(item)">
|
<div class="item" :key="i" v-for="(item, i) in data.list" @click="goDetail(item)">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{ item.title }}
|
{{ item.title }}
|
||||||
<div class="ml1r not-read" v-if="!item.read"></div>
|
<div class="ml1r not-read" v-if="!item.read"></div>
|
||||||
@ -32,30 +32,30 @@
|
|||||||
</Scroll>
|
</Scroll>
|
||||||
|
|
||||||
<!--TODO 子页面未做-->
|
<!--TODO 子页面未做-->
|
||||||
<div class="hover-dialog left" v-if="isShowLeftHover">
|
<div class="hover-dialog left" v-if="data.isShowLeftHover">
|
||||||
<div class="arrow"></div>
|
<div class="arrow"></div>
|
||||||
<div class="l-row no-border" @click="$no">登录设备管理</div>
|
<div class="l-row no-border" @click="_no">登录设备管理</div>
|
||||||
<div class="l-row" @click="$no">账号锁定</div>
|
<div class="l-row" @click="_no">账号锁定</div>
|
||||||
<div class="l-row" @click="$no">账号解锁</div>
|
<div class="l-row" @click="_no">账号解锁</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="hover-dialog right" v-if="isShowRightHover">
|
<div class="hover-dialog right" v-if="data.isShowRightHover">
|
||||||
<div class="arrow"></div>
|
<div class="arrow"></div>
|
||||||
<div class="l-row no-border" @click="$no">常见问题</div>
|
<div class="l-row no-border" @click="_no">常见问题</div>
|
||||||
<div class="l-row" @click="$no">安全课堂</div>
|
<div class="l-row" @click="_no">安全课堂</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<BaseMask mode="white" v-if="isShowMask" @click="isShowMask = false" />
|
<BaseMask mode="white" v-if="data.isShowMask" @click="data.isShowMask = false" />
|
||||||
|
|
||||||
<div class="options">
|
<div class="options">
|
||||||
<div class="option" @click="isShowLeftHover = !isShowLeftHover">
|
<div class="option" @click="data.isShowLeftHover = !data.isShowLeftHover">
|
||||||
<img src="../../../assets/img/icon/message/menu-thin.png" alt="" />
|
<img src="../../../assets/img/icon/message/menu-thin.png" alt="" />
|
||||||
<span>自助工具</span>
|
<span>自助工具</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="option" @click="$no">
|
<div class="option" @click="_no">
|
||||||
<span>规则中心</span>
|
<span>规则中心</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="option" @click="isShowRightHover = !isShowRightHover">
|
<div class="option" @click="data.isShowRightHover = !data.isShowRightHover">
|
||||||
<img src="../../../assets/img/icon/message/menu-thin.png" alt="" />
|
<img src="../../../assets/img/icon/message/menu-thin.png" alt="" />
|
||||||
<span>更多帮助</span>
|
<span>更多帮助</span>
|
||||||
</div>
|
</div>
|
||||||
@ -63,94 +63,102 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import { nextTick } from 'vue'
|
import { nextTick, onMounted, reactive, watch } from 'vue'
|
||||||
import Scroll from '../../../components/Scroll'
|
import Scroll from '@/components/Scroll.vue'
|
||||||
import BasePage from '../../BasePage'
|
import { useNav } from '@/utils/hooks/useNav.js'
|
||||||
|
import { _no, _sleep } from '@/utils'
|
||||||
|
|
||||||
export default {
|
defineOptions({
|
||||||
extends: BasePage,
|
name: 'SystemNotice'
|
||||||
name: 'SystemNotice',
|
})
|
||||||
components: { Scroll },
|
|
||||||
data() {
|
const nav = useNav()
|
||||||
return {
|
const data = reactive({
|
||||||
loading: false,
|
loading: false,
|
||||||
isShowMask: false,
|
isShowMask: false,
|
||||||
isShowLeftHover: false,
|
isShowLeftHover: false,
|
||||||
isShowRightHover: false,
|
isShowRightHover: false,
|
||||||
list: [
|
list: [
|
||||||
{
|
{
|
||||||
read: false,
|
read: false,
|
||||||
title: '账号登录提醒',
|
title: '账号登录提醒',
|
||||||
detail: 'xxx',
|
detail: 'xxx',
|
||||||
time: '2021-10-12 12:12',
|
time: '2021-10-12 12:12',
|
||||||
content:
|
content:
|
||||||
'您的抖音号4533452342于2021-02-09 07:45:23进行了登录操作。如非本人操作,账号可能被盗。建议立即修改密码,或在[设置-账号与安全-登录设备管理]中删除异常设备。参考设备:iPhone X参考地点:上海市'
|
'您的抖音号4533452342于2021-02-09 07:45:23进行了登录操作。如非本人操作,账号可能被盗。建议立即修改密码,或在[设置-账号与安全-登录设备管理]中删除异常设备。参考设备:iPhone X参考地点:上海市'
|
||||||
},
|
|
||||||
{
|
|
||||||
read: false,
|
|
||||||
title: '账号登录提醒',
|
|
||||||
detail: 'xxx',
|
|
||||||
time: '2021-10-12 12:12',
|
|
||||||
content:
|
|
||||||
'您的抖音号4533452342于2021-02-09 07:45:23进行了登录操作。如非本人操作,账号可能被盗。建议立即修改密码,或在[设置-账号与安全-登录设备管理]中删除异常设备。参考设备:iPhone X参考地点:上海市'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
read: false,
|
|
||||||
title: '协议修订通知',
|
|
||||||
detail: '',
|
|
||||||
time: '2021-10-12 12:12',
|
|
||||||
content:
|
|
||||||
'你好,根据业务开展的实际情况,抖音近期更新了《抖音用户服务协议》《抖音隐私政策》及《儿童/青少年使用须知》中的相关内容。你可以在“我”-“设置”页面中,查看更新后的协议全文。'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
read: false,
|
|
||||||
title: '协议修订通知',
|
|
||||||
detail: '',
|
|
||||||
time: '2021-10-12 12:12',
|
|
||||||
content:
|
|
||||||
'你好,根据业务开展的实际情况,抖音近期更新了《抖音用户服务协议》部分条款的表述。你可以在“我”-“设置”页面中,查看更新后的协议全文。'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
isShowLeftHover(newVal) {
|
|
||||||
if (newVal) {
|
|
||||||
this.isShowMask = true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
isShowRightHover(newVal) {
|
{
|
||||||
if (newVal) {
|
read: false,
|
||||||
this.isShowMask = true
|
title: '账号登录提醒',
|
||||||
}
|
detail: 'xxx',
|
||||||
|
time: '2021-10-12 12:12',
|
||||||
|
content:
|
||||||
|
'您的抖音号4533452342于2021-02-09 07:45:23进行了登录操作。如非本人操作,账号可能被盗。建议立即修改密码,或在[设置-账号与安全-登录设备管理]中删除异常设备。参考设备:iPhone X参考地点:上海市'
|
||||||
},
|
},
|
||||||
isShowMask(newVal) {
|
{
|
||||||
if (!newVal) {
|
read: false,
|
||||||
this.isShowLeftHover = false
|
title: '协议修订通知',
|
||||||
this.isShowRightHover = false
|
detail: '',
|
||||||
}
|
time: '2021-10-12 12:12',
|
||||||
}
|
content:
|
||||||
},
|
'你好,根据业务开展的实际情况,抖音近期更新了《抖音用户服务协议》《抖音隐私政策》及《儿童/青少年使用须知》中的相关内容。你可以在“我”-“设置”页面中,查看更新后的协议全文。'
|
||||||
computed: {},
|
|
||||||
created() {
|
|
||||||
this.getData()
|
|
||||||
},
|
|
||||||
mounted() {},
|
|
||||||
methods: {
|
|
||||||
async getData() {
|
|
||||||
this.loading = true
|
|
||||||
await this.$sleep(700)
|
|
||||||
this.loading = false
|
|
||||||
await nextTick()
|
|
||||||
this.$refs.mainScroll.scrollBottom()
|
|
||||||
},
|
},
|
||||||
goDetail(item) {
|
{
|
||||||
item.read = true
|
read: false,
|
||||||
if (item.detail) {
|
title: '协议修订通知',
|
||||||
this.$no()
|
detail: '',
|
||||||
}
|
time: '2021-10-12 12:12',
|
||||||
|
content:
|
||||||
|
'你好,根据业务开展的实际情况,抖音近期更新了《抖音用户服务协议》部分条款的表述。你可以在“我”-“设置”页面中,查看更新后的协议全文。'
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getData()
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => data.isShowLeftHover,
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
data.isShowMask = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => data.isShowRightHover,
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
data.isShowMask = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => data.isShowMask,
|
||||||
|
(newVal) => {
|
||||||
|
if (!newVal) {
|
||||||
|
data.isShowLeftHover = false
|
||||||
|
data.isShowRightHover = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
async function getData() {
|
||||||
|
data.loading = true
|
||||||
|
await _sleep(700)
|
||||||
|
data.loading = false
|
||||||
|
await nextTick()
|
||||||
|
// data.$refs.mainScroll.scrollBottom()
|
||||||
|
}
|
||||||
|
|
||||||
|
function goDetail(item) {
|
||||||
|
item.read = true
|
||||||
|
if (item.detail) {
|
||||||
|
_no()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<div class="goods-detail base-page" ref="page" @scroll="scroll">
|
<div class="goods-detail base-page" ref="page" @scroll="scroll">
|
||||||
<header ref="header">
|
<header ref="header">
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<Icon @click="$back()" icon="material-symbols-light:arrow-back-ios-new" />
|
<Icon @click="router.back()" icon="material-symbols-light:arrow-back-ios-new" />
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="search">
|
<div class="search">
|
||||||
<Icon icon="jam:search" />
|
<Icon icon="jam:search" />
|
||||||
@ -18,7 +18,7 @@
|
|||||||
</header>
|
</header>
|
||||||
<header class="shadow" ref="headerShadow">
|
<header class="shadow" ref="headerShadow">
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<Icon @click="$back()" icon="material-symbols-light:arrow-back-ios-new" />
|
<Icon @click="router.back()" icon="material-symbols-light:arrow-back-ios-new" />
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="search">
|
<div class="search">
|
||||||
<Icon icon="jam:search" />
|
<Icon icon="jam:search" />
|
||||||
@ -347,7 +347,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import SlideHorizontal from '@/components/slide/SlideHorizontal.vue'
|
import SlideHorizontal from '@/components/slide/SlideHorizontal.vue'
|
||||||
import SlideItem from '@/components/slide/SlideItem.vue'
|
import SlideItem from '@/components/slide/SlideItem.vue'
|
||||||
import { onMounted, onUnmounted, reactive, ref } from 'vue'
|
import { onMounted, onUnmounted, reactive, ref } from 'vue'
|
||||||
@ -357,11 +357,13 @@ import { useBaseStore } from '@/store/pinia'
|
|||||||
import { recommendedShop } from '@/api/user'
|
import { recommendedShop } from '@/api/user'
|
||||||
import WaterfallList from '@/components/WaterfallList.vue'
|
import WaterfallList from '@/components/WaterfallList.vue'
|
||||||
import ScrollList from '@/components/ScrollList.vue'
|
import ScrollList from '@/components/ScrollList.vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'GoodsDetail'
|
name: 'GoodsDetail'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
let activeIndexs = ref([])
|
let activeIndexs = ref([])
|
||||||
const nav = useNav()
|
const nav = useNav()
|
||||||
const store = useBaseStore()
|
const store = useBaseStore()
|
||||||
@ -382,6 +384,10 @@ function scroll() {
|
|||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
detail: {
|
detail: {
|
||||||
|
price: '',
|
||||||
|
name: '',
|
||||||
|
sold: '',
|
||||||
|
real_price: '',
|
||||||
imgs: []
|
imgs: []
|
||||||
},
|
},
|
||||||
index: 0,
|
index: 0,
|
||||||
|
|||||||
@ -112,7 +112,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="jsx">
|
<script setup lang="tsx">
|
||||||
import { useNav } from '@/utils/hooks/useNav'
|
import { useNav } from '@/utils/hooks/useNav'
|
||||||
import { $no, _checkImgUrl } from '@/utils'
|
import { $no, _checkImgUrl } from '@/utils'
|
||||||
import ScrollList from '@/components/ScrollList.vue'
|
import ScrollList from '@/components/ScrollList.vue'
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<!-- <video ref="videoEl" :src="v1" controls></video>-->
|
<!-- <video ref="videoEl" :src="v1" controls></video>-->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import { onMounted, ref } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
|
|||||||
@ -5,30 +5,12 @@
|
|||||||
<VideoShare v-model="t" page-id="Test" />
|
<VideoShare v-model="t" page-id="Test" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import BaseButton from '../../components/BaseButton'
|
import BaseButton from '../../components/BaseButton.vue'
|
||||||
import VideoShare from '../home/components/VideoShare'
|
import VideoShare from '../home/components/VideoShare.vue'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
export default {
|
const t = ref(false)
|
||||||
name: 'Test4',
|
|
||||||
components: {
|
|
||||||
BaseButton,
|
|
||||||
VideoShare
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
text: {
|
|
||||||
type: String,
|
|
||||||
default: '@喵嗷污说电影创作的原声'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
t: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {},
|
|
||||||
mounted() {}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const router = createRouter({
|
|||||||
router.beforeEach((to, from) => {
|
router.beforeEach((to, from) => {
|
||||||
const baseStore = useBaseStore()
|
const baseStore = useBaseStore()
|
||||||
//footer下面的5个按钮,对跳不要用动画
|
//footer下面的5个按钮,对跳不要用动画
|
||||||
let noAnimation = ['/', '/home', '/me', '/shop', '/message', '/publish', '/home/live', '/test']
|
const noAnimation = ['/', '/home', '/me', '/shop', '/message', '/publish', '/home/live', '/test']
|
||||||
if (noAnimation.indexOf(from.path) !== -1 && noAnimation.indexOf(to.path) !== -1) {
|
if (noAnimation.indexOf(from.path) !== -1 && noAnimation.indexOf(to.path) !== -1) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -28,7 +28,7 @@ router.beforeEach((to, from) => {
|
|||||||
|
|
||||||
if (toDepth > fromDepth) {
|
if (toDepth > fromDepth) {
|
||||||
if (to.matched && to.matched.length) {
|
if (to.matched && to.matched.length) {
|
||||||
let toComponentName = to.matched[0].components.default.name
|
const toComponentName = to.matched[0].components?.default.name
|
||||||
// store.commit('updateExcludeRoutes', {type: 'remove', value: toComponentName})
|
// store.commit('updateExcludeRoutes', {type: 'remove', value: toComponentName})
|
||||||
baseStore.updateExcludeRoutes({ type: 'remove', value: toComponentName })
|
baseStore.updateExcludeRoutes({ type: 'remove', value: toComponentName })
|
||||||
// console.log('to', toComponentName)
|
// console.log('to', toComponentName)
|
||||||
@ -37,7 +37,7 @@ router.beforeEach((to, from) => {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (from.matched && from.matched.length) {
|
if (from.matched && from.matched.length) {
|
||||||
let fromComponentName = from.matched[0].components.default.name
|
const fromComponentName = from.matched[0].components?.default.name
|
||||||
// store.commit('updateExcludeRoutes', {type: 'add', value: fromComponentName})
|
// store.commit('updateExcludeRoutes', {type: 'add', value: fromComponentName})
|
||||||
baseStore.updateExcludeRoutes({ type: 'add', value: fromComponentName })
|
baseStore.updateExcludeRoutes({ type: 'add', value: fromComponentName })
|
||||||
|
|
||||||
@ -1,8 +1,9 @@
|
|||||||
import Home from '../pages/home'
|
import Home from '../pages/home/index.vue'
|
||||||
import Test from '../pages/test/Test'
|
import Test from '../pages/test/Test.vue'
|
||||||
import Test4 from '../pages/test/Test4'
|
import Test4 from '../pages/test/Test4.vue'
|
||||||
|
import type { RouteRecordRaw } from 'vue-router'
|
||||||
|
|
||||||
const routes = [
|
const routes: RouteRecordRaw[] = [
|
||||||
// {path: '/', redirect: '/attention'},
|
// {path: '/', redirect: '/attention'},
|
||||||
{ path: '/', redirect: '/home' },
|
{ path: '/', redirect: '/home' },
|
||||||
{ path: '/test', component: Test },
|
{ path: '/test', component: Test },
|
||||||
@ -18,6 +18,14 @@ export const useBaseStore = defineStore('base', {
|
|||||||
routeData: null,
|
routeData: null,
|
||||||
users: [],
|
users: [],
|
||||||
userinfo: {
|
userinfo: {
|
||||||
|
nickname: '',
|
||||||
|
desc: '',
|
||||||
|
user_age: '',
|
||||||
|
signature: '',
|
||||||
|
unique_id: '',
|
||||||
|
province: '',
|
||||||
|
city: '',
|
||||||
|
gender: '',
|
||||||
school: {
|
school: {
|
||||||
name: '',
|
name: '',
|
||||||
department: null,
|
department: null,
|
||||||
|
|||||||
@ -47,7 +47,12 @@ export const SlideItemPlayStatus = {
|
|||||||
export const DefaultUser = {
|
export const DefaultUser = {
|
||||||
nickname: '',
|
nickname: '',
|
||||||
unique_id: '',
|
unique_id: '',
|
||||||
|
certification: '',
|
||||||
short_id: '',
|
short_id: '',
|
||||||
|
province: '',
|
||||||
|
city: '',
|
||||||
|
school: {},
|
||||||
|
uid: '',
|
||||||
signature: '', //签名
|
signature: '', //签名
|
||||||
mplatform_followers_count: '', //粉丝
|
mplatform_followers_count: '', //粉丝
|
||||||
following_count: '', //关注
|
following_count: '', //关注
|
||||||
|
|||||||
@ -427,6 +427,10 @@ const Utils = {
|
|||||||
|
|
||||||
export default Utils
|
export default Utils
|
||||||
|
|
||||||
|
export function _dateFormat(val, type) {
|
||||||
|
return Utils.$dateFormat(val, type)
|
||||||
|
}
|
||||||
|
|
||||||
export function $no() {
|
export function $no() {
|
||||||
Utils.$no(arguments)
|
Utils.$no(arguments)
|
||||||
}
|
}
|
||||||
@ -435,8 +439,8 @@ export function $notice(val) {
|
|||||||
Utils.$notice(val)
|
Utils.$notice(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _notice(val) {
|
export function _time(val) {
|
||||||
Utils.$notice(val)
|
return Utils.$time(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _checkImgUrl(url) {
|
export function _checkImgUrl(url) {
|
||||||
@ -467,6 +471,9 @@ export function _getUserDouyinId(item) {
|
|||||||
return item.author.unique_id || item.author.short_id
|
return item.author.unique_id || item.author.short_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} duration
|
||||||
|
*/
|
||||||
export function _sleep(duration) {
|
export function _sleep(duration) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
setTimeout(resolve, duration)
|
setTimeout(resolve, duration)
|
||||||
@ -499,3 +506,176 @@ export function sampleSize(arr, num) {
|
|||||||
}
|
}
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function _showLoading() {
|
||||||
|
const app = Vue.createApp({
|
||||||
|
render() {
|
||||||
|
return <Loading />
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let parent = document.createElement('div')
|
||||||
|
parent.classList.add(...['dialog-ctn'])
|
||||||
|
document.body.append(parent)
|
||||||
|
app.mount(parent)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function _hideLoading() {
|
||||||
|
let parent = document.querySelector('.dialog-ctn')
|
||||||
|
parent.remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
export function _showSelectDialog(sexList, cb) {
|
||||||
|
let remove = () => {
|
||||||
|
let parent = document.querySelector('.dialog-ctn')
|
||||||
|
parent.classList.replace('fade-in', 'fade-out')
|
||||||
|
setTimeout(() => {
|
||||||
|
parent.remove()
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
let tempCb = (e) => {
|
||||||
|
remove()
|
||||||
|
cb(e)
|
||||||
|
}
|
||||||
|
const app = Vue.createApp({
|
||||||
|
render() {
|
||||||
|
return <SelectDialog onCancel={remove} list={sexList} onOk={tempCb} />
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let parent = document.createElement('div')
|
||||||
|
parent.classList.add(...['dialog-ctn', 'fade-in'])
|
||||||
|
document.body.append(parent)
|
||||||
|
app.mount(parent)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function _showSimpleConfirmDialog(title, okCb, cancelCb, okText, cancelText) {
|
||||||
|
if (!cancelCb) {
|
||||||
|
cancelCb = () => {}
|
||||||
|
}
|
||||||
|
let remove = () => {
|
||||||
|
let parent = document.querySelector('.dialog-ctn')
|
||||||
|
parent.classList.replace('fade-in', 'fade-out')
|
||||||
|
setTimeout(() => {
|
||||||
|
parent.remove()
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
let tempOkCb = (e) => {
|
||||||
|
remove()
|
||||||
|
okCb(e)
|
||||||
|
}
|
||||||
|
let tempCancelCb = (e) => {
|
||||||
|
remove()
|
||||||
|
cancelCb(e)
|
||||||
|
}
|
||||||
|
const app = Vue.createApp({
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<SimpleConfirmDialog
|
||||||
|
onCancel={tempCancelCb}
|
||||||
|
onDismiss={remove}
|
||||||
|
title={title}
|
||||||
|
okText={okText}
|
||||||
|
cancelText={cancelText}
|
||||||
|
onOk={tempOkCb}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let parent = document.createElement('div')
|
||||||
|
parent.classList.add(...['dialog-ctn', 'fade-in'])
|
||||||
|
document.body.append(parent)
|
||||||
|
app.mount(parent)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function _showConfirmDialog(
|
||||||
|
title,
|
||||||
|
subtitle,
|
||||||
|
subtitleColor,
|
||||||
|
okCb,
|
||||||
|
cancelCb,
|
||||||
|
okText,
|
||||||
|
cancelText,
|
||||||
|
cancelTextColor
|
||||||
|
) {
|
||||||
|
let remove = () => {
|
||||||
|
let parent = document.querySelector('.dialog-ctn')
|
||||||
|
parent.classList.replace('fade-in', 'fade-out')
|
||||||
|
setTimeout(() => {
|
||||||
|
parent.remove()
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
let tempOkCb = (e) => {
|
||||||
|
remove()
|
||||||
|
okCb && okCb(e)
|
||||||
|
}
|
||||||
|
let tempCancelCb = (e) => {
|
||||||
|
remove()
|
||||||
|
cancelCb && cancelCb(e)
|
||||||
|
}
|
||||||
|
const app = Vue.createApp({
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<ConfirmDialog
|
||||||
|
onCancel={tempCancelCb}
|
||||||
|
onDismiss={remove}
|
||||||
|
title={title}
|
||||||
|
subtitle={subtitle}
|
||||||
|
subtitleColor={subtitleColor}
|
||||||
|
cancelTextColor={cancelTextColor}
|
||||||
|
okText={okText}
|
||||||
|
cancelText={cancelText}
|
||||||
|
onOk={tempOkCb}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let parent = document.createElement('div')
|
||||||
|
parent.classList.add(...['dialog-ctn', 'fade-in'])
|
||||||
|
document.body.append(parent)
|
||||||
|
app.mount(parent)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function _showNoticeDialog(title, subtitle, subtitleColor, cancelCb, cancelText) {
|
||||||
|
let remove = () => {
|
||||||
|
let parent = document.querySelector('.dialog-ctn')
|
||||||
|
parent.classList.replace('fade-in', 'fade-out')
|
||||||
|
setTimeout(() => {
|
||||||
|
parent.remove()
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
let tempCancelCb = (e) => {
|
||||||
|
remove()
|
||||||
|
cancelCb(e)
|
||||||
|
}
|
||||||
|
const app = Vue.createApp({
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<NoticeDialog
|
||||||
|
onCancel={tempCancelCb}
|
||||||
|
onDismiss={remove}
|
||||||
|
title={title}
|
||||||
|
subtitleColor={subtitleColor}
|
||||||
|
cancelText={cancelText}
|
||||||
|
subtitle={subtitle}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let parent = document.createElement('div')
|
||||||
|
parent.classList.add(...['dialog-ctn', 'fade-in'])
|
||||||
|
document.body.append(parent)
|
||||||
|
app.mount(parent)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function _notice(val) {
|
||||||
|
let div = document.createElement('div')
|
||||||
|
div.classList.add('global-notice')
|
||||||
|
div.textContent = val
|
||||||
|
document.body.append(div)
|
||||||
|
setTimeout(() => {
|
||||||
|
document.body.removeChild(div)
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function _no() {
|
||||||
|
this.$notice('未实现')
|
||||||
|
}
|
||||||
|
|||||||
23
tsconfig.app.json
Normal file
23
tsconfig.app.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||||
|
"include": [
|
||||||
|
"env.d.ts",
|
||||||
|
"src/**/*",
|
||||||
|
"src/**/*.vue"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"src/**/__tests__/*"
|
||||||
|
],
|
||||||
|
"compilerOptions": {
|
||||||
|
"allowJs": true,
|
||||||
|
"strict": false,
|
||||||
|
"composite": true,
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"./src/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
tsconfig.json
Normal file
11
tsconfig.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.node.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.app.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
19
tsconfig.node.json
Normal file
19
tsconfig.node.json
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"extends": "@tsconfig/node20/tsconfig.json",
|
||||||
|
"include": [
|
||||||
|
"vite.config.*",
|
||||||
|
"vitest.config.*",
|
||||||
|
"cypress.config.*",
|
||||||
|
"nightwatch.conf.*",
|
||||||
|
"playwright.config.*"
|
||||||
|
],
|
||||||
|
"compilerOptions": {
|
||||||
|
"composite": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||||
|
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"types": ["node"]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,20 +1,23 @@
|
|||||||
import { defineConfig } from 'vite'
|
import { defineConfig, PluginOption } from 'vite'
|
||||||
import Vue from '@vitejs/plugin-vue'
|
import Vue from '@vitejs/plugin-vue'
|
||||||
import VueJsx from '@vitejs/plugin-vue-jsx'
|
import VueJsx from '@vitejs/plugin-vue-jsx'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import { visualizer } from 'rollup-plugin-visualizer'
|
import { visualizer } from 'rollup-plugin-visualizer'
|
||||||
import DefineOptions from 'unplugin-vue-define-options/vite' // 引入插件
|
import DefineOptions from 'unplugin-vue-define-options/vite' // 引入插件
|
||||||
import { Plugin as importToCDN } from 'vite-plugin-cdn-import'
|
import { Plugin as importToCDN } from 'vite-plugin-cdn-import'
|
||||||
|
import commonjs from 'vite-plugin-commonjs'
|
||||||
|
import { fileURLToPath, URL } from 'node:url'
|
||||||
|
|
||||||
// import viteImagemin from 'vite-plugin-imagemin'
|
// import viteImagemin from 'vite-plugin-imagemin'
|
||||||
// import viteCompression from 'vite-plugin-compression'
|
// import viteCompression from 'vite-plugin-compression'
|
||||||
|
|
||||||
function pathResolve(dir) {
|
|
||||||
return resolve(__dirname, '.', dir)
|
|
||||||
}
|
|
||||||
|
|
||||||
const lifecycle = process.env.npm_lifecycle_event
|
const lifecycle = process.env.npm_lifecycle_event
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// {
|
||||||
|
// name: 'axios',
|
||||||
|
// var: 'axios',
|
||||||
|
// path: 'https://lib.baomitu.com/axios/1.6.8/axios.min.js'
|
||||||
|
// },
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
base: './',
|
base: './',
|
||||||
envDir: 'env',
|
envDir: 'env',
|
||||||
@ -29,7 +32,7 @@ export default defineConfig({
|
|||||||
// // exclude: [/node_modules/, /jQuery\.js/]
|
// // exclude: [/node_modules/, /jQuery\.js/]
|
||||||
// // }
|
// // }
|
||||||
// }),
|
// }),
|
||||||
lifecycle === 'report' ? visualizer({ open: false }) : null,
|
lifecycle === 'report' ? (visualizer({ open: false }) as any as PluginOption) : null,
|
||||||
DefineOptions(),
|
DefineOptions(),
|
||||||
Vue(),
|
Vue(),
|
||||||
VueJsx(),
|
VueJsx(),
|
||||||
@ -55,11 +58,7 @@ export default defineConfig({
|
|||||||
var: 'Mock',
|
var: 'Mock',
|
||||||
path: 'https://lib.baomitu.com/Mock.js/1.0.1-beta3/mock-min.js'
|
path: 'https://lib.baomitu.com/Mock.js/1.0.1-beta3/mock-min.js'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'axios',
|
|
||||||
var: 'axios',
|
|
||||||
path: 'https://lib.baomitu.com/axios/1.6.8/axios.min.js'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'jquery',
|
name: 'jquery',
|
||||||
var: '$',
|
var: '$',
|
||||||
@ -109,7 +108,7 @@ export default defineConfig({
|
|||||||
],
|
],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': pathResolve('src')
|
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||||
},
|
},
|
||||||
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
|
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
|
||||||
},
|
},
|
||||||
@ -121,7 +120,7 @@ export default defineConfig({
|
|||||||
manualChunks(id, { getModuleInfo }) {
|
manualChunks(id, { getModuleInfo }) {
|
||||||
const reg = /(.*)\/src\/components\/(.*)/
|
const reg = /(.*)\/src\/components\/(.*)/
|
||||||
if (reg.test(id)) {
|
if (reg.test(id)) {
|
||||||
const importersLen = getModuleInfo(id).importers.length
|
const importersLen = getModuleInfo(id)?.importers.length ?? 0
|
||||||
// 被多处引用
|
// 被多处引用
|
||||||
if (importersLen > 1) return 'common'
|
if (importersLen > 1) return 'common'
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user