提交 70a16728 authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 8522d69a
{
"globals": {
"$": true,
"$$": true,
"$computed": true,
"$customRef": true,
"$ref": true,
"$shallowRef": true,
"$toRef": true,
"asyncComputed": true,
"autoResetRef": true,
"computed": true,
"computedAsync": true,
"computedEager": true,
"computedInject": true,
"computedWithControl": true,
"controlledComputed": true,
"controlledRef": true,
"createApp": true,
"createEventHook": true,
"createGlobalState": true,
"createInjectionState": true,
"createReactiveFn": true,
"createSharedComposable": true,
"createUnrefFn": true,
"customRef": true,
"debouncedRef": true,
"debouncedWatch": true,
"defineAsyncComponent": true,
"defineComponent": true,
"eagerComputed": true,
"effectScope": true,
"EffectScope": true,
"extendRef": true,
"getCurrentInstance": true,
"getCurrentScope": true,
"h": true,
"ignorableWatch": true,
"inject": true,
"isDefined": true,
"isReadonly": true,
"isRef": true,
"logicAnd": true,
"logicNot": true,
"logicOr": true,
"makeDestructurable": true,
"markRaw": true,
"nextTick": true,
"onActivated": true,
"onBeforeMount": true,
"onBeforeUnmount": true,
"onBeforeUpdate": true,
"onClickOutside": true,
"onDeactivated": true,
"onErrorCaptured": true,
"onKeyStroke": true,
"onLongPress": true,
"onMounted": true,
"onRenderTracked": true,
"onRenderTriggered": true,
"onScopeDispose": true,
"onServerPrefetch": true,
"onStartTyping": true,
"onUnmounted": true,
"onUpdated": true,
"pausableWatch": true,
"provide": true,
"reactify": true,
"reactifyObject": true,
"reactive": true,
"reactiveComputed": true,
"reactiveOmit": true,
"reactivePick": true,
"readonly": true,
"ref": true,
"refAutoReset": true,
"refDebounced": true,
"refDefault": true,
"refThrottled": true,
"refWithControl": true,
"resolveComponent": true,
"shallowReactive": true,
"shallowReadonly": true,
"shallowRef": true,
"syncRef": true,
"syncRefs": true,
"templateRef": true,
"throttledRef": true,
"throttledWatch": true,
"toRaw": true,
"toReactive": true,
"toRef": true,
"toRefs": true,
"triggerRef": true,
"tryOnBeforeMount": true,
"tryOnBeforeUnmount": true,
"tryOnMounted": true,
"tryOnScopeDispose": true,
"tryOnUnmounted": true,
"unref": true,
"unrefElement": true,
"until": true,
"useActiveElement": true,
"useAsyncQueue": true,
"useAsyncState": true,
"useAttrs": true,
"useBase64": true,
"useBattery": true,
"useBreakpoints": true,
"useBroadcastChannel": true,
"useBrowserLocation": true,
"useCached": true,
"useClamp": true,
"useClipboard": true,
"useColorMode": true,
"useConfirmDialog": true,
"useCounter": true,
"useCssModule": true,
"useCssVar": true,
"useCssVars": true,
"useCurrentElement": true,
"useCycleList": true,
"useDark": true,
"useDateFormat": true,
"useDebounce": true,
"useDebouncedRefHistory": true,
"useDebounceFn": true,
"useDeviceMotion": true,
"useDeviceOrientation": true,
"useDevicePixelRatio": true,
"useDevicesList": true,
"useDisplayMedia": true,
"useDocumentVisibility": true,
"useDraggable": true,
"useElementBounding": true,
"useElementByPoint": true,
"useElementHover": true,
"useElementSize": true,
"useElementVisibility": true,
"useEventBus": true,
"useEventListener": true,
"useEventSource": true,
"useEyeDropper": true,
"useFavicon": true,
"useFetch": true,
"useFileSystemAccess": true,
"useFocus": true,
"useFocusWithin": true,
"useFps": true,
"useFullscreen": true,
"useGamepad": true,
"useGeolocation": true,
"useIdle": true,
"useInfiniteScroll": true,
"useIntersectionObserver": true,
"useInterval": true,
"useIntervalFn": true,
"useKeyModifier": true,
"useLastChanged": true,
"useLocalStorage": true,
"useMagicKeys": true,
"useManualRefHistory": true,
"useMediaControls": true,
"useMediaQuery": true,
"useMemoize": true,
"useMemory": true,
"useMounted": true,
"useMouse": true,
"useMouseInElement": true,
"useMousePressed": true,
"useMutationObserver": true,
"useNavigatorLanguage": true,
"useNetwork": true,
"useNow": true,
"useOffsetPagination": true,
"useOnline": true,
"usePageLeave": true,
"useParallax": true,
"usePermission": true,
"usePointer": true,
"usePointerSwipe": true,
"usePreferredColorScheme": true,
"usePreferredDark": true,
"usePreferredLanguages": true,
"useRafFn": true,
"useRefHistory": true,
"useResizeObserver": true,
"useRoute": true,
"useRouter": true,
"useScreenOrientation": true,
"useScreenSafeArea": true,
"useScriptTag": true,
"useScroll": true,
"useScrollLock": true,
"useSessionStorage": true,
"useShare": true,
"useSlots": true,
"useSpeechRecognition": true,
"useSpeechSynthesis": true,
"useStorage": true,
"useStorageAsync": true,
"useStyleTag": true,
"useSwipe": true,
"useTemplateRefsList": true,
"useTextSelection": true,
"useThrottle": true,
"useThrottledRefHistory": true,
"useThrottleFn": true,
"useTimeAgo": true,
"useTimeout": true,
"useTimeoutFn": true,
"useTimeoutPoll": true,
"useTimestamp": true,
"useTitle": true,
"useToggle": true,
"useTransition": true,
"useUrlSearchParams": true,
"useUserMedia": true,
"useVibrate": true,
"useVirtualList": true,
"useVModel": true,
"useVModels": true,
"useWakeLock": true,
"useWebNotification": true,
"useWebSocket": true,
"useWebWorker": true,
"useWebWorkerFn": true,
"useWindowFocus": true,
"useWindowScroll": true,
"useWindowSize": true,
"watch": true,
"watchAtMost": true,
"watchDebounced": true,
"watchEffect": true,
"watchIgnorable": true,
"watchOnce": true,
"watchPausable": true,
"watchThrottled": true,
"watchWithFilter": true,
"whenever": true
}
}
\ No newline at end of file
...@@ -3,12 +3,20 @@ require('@rushstack/eslint-patch/modern-module-resolution') ...@@ -3,12 +3,20 @@ require('@rushstack/eslint-patch/modern-module-resolution')
module.exports = { module.exports = {
root: true, root: true,
extends: ['plugin:vue/vue3-essential', 'eslint:recommended', '@vue/eslint-config-typescript/recommended'], extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/eslint-config-typescript/recommended',
'./.eslintrc-auto-import.json'
],
env: { env: {
'vue/setup-compiler-macros': true 'vue/setup-compiler-macros': true
}, },
rules: { rules: {
'vue/multi-word-component-names': 'off', 'vue/multi-word-component-names': 'off',
'@typescript-eslint/no-explicit-any': 'off' '@typescript-eslint/no-explicit-any': 'off'
},
globals: {
wx: true
} }
} }
差异被折叠。
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover"
/> />
<title>PRP私享星球</title> <title>PRP私享星球</title>
<script src="https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script> <script>
;(function (win, doc) { ;(function (win, doc) {
function resizeRoot() { function resizeRoot() {
......
...@@ -13,35 +13,36 @@ ...@@ -13,35 +13,36 @@
"deploy": "node ./deploy.js" "deploy": "node ./deploy.js"
}, },
"dependencies": { "dependencies": {
"@vueuse/core": "^8.2.6", "@vueuse/core": "^8.4.2",
"axios": "^0.26.1", "axios": "^0.27.2",
"blueimp-md5": "^2.19.0", "blueimp-md5": "^2.19.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"pinia": "^2.0.13", "pinia": "^2.0.14",
"qs": "^6.10.3", "qs": "^6.10.3",
"sass": "^1.50.1", "sass": "^1.51.0",
"swiper": "^8.1.1", "swiper": "^8.1.4",
"vant": "^3.4.8", "vant": "^3.4.9",
"vue": "^3.2.33", "vue": "^3.2.33",
"vue-infinite-scroll": "^2.0.2", "vue-infinite-scroll": "^2.0.2",
"vue-router": "^4.0.14" "vue-router": "^4.0.15"
}, },
"devDependencies": { "devDependencies": {
"@rushstack/eslint-patch": "^1.1.3", "@rushstack/eslint-patch": "^1.1.3",
"@types/blueimp-md5": "^2.18.0", "@types/blueimp-md5": "^2.18.0",
"@types/lodash-es": "^4.17.6", "@types/lodash-es": "^4.17.6",
"@types/node": "^17.0.25", "@types/node": "^17.0.32",
"@types/qs": "^6.9.7", "@types/qs": "^6.9.7",
"@vitejs/plugin-vue": "^2.3.1", "@vitejs/plugin-vue": "^2.3.3",
"@vue/eslint-config-typescript": "^10.0.0", "@vue/eslint-config-typescript": "^10.0.0",
"@vue/tsconfig": "^0.1.3", "@vue/tsconfig": "^0.1.3",
"ali-oss": "^6.17.1", "ali-oss": "^6.17.1",
"chalk": "^5.0.1", "chalk": "^5.0.1",
"eslint": "^8.13.0", "eslint": "^8.15.0",
"eslint-plugin-vue": "^8.6.0", "eslint-plugin-vue": "^8.7.1",
"typescript": "~4.6.3", "typescript": "~4.6.4",
"vite": "^2.9.5", "unplugin-auto-import": "^0.7.1",
"vite": "^2.9.9",
"vite-plugin-checker": "^0.4.6", "vite-plugin-checker": "^0.4.6",
"vue-tsc": "^0.34.7" "vue-tsc": "^0.34.13"
} }
} }
差异被折叠。
<script lang="ts">
export default {
name: 'PublishItem'
}
</script>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, nextTick } from 'vue' import { ref, computed, nextTick } from 'vue'
import { ImagePreview } from 'vant' import { ImagePreview } from 'vant'
const props = defineProps<{ data: any }>() const props = defineProps<{ data: any }>()
const emit = defineEmits(['submitComment', 'load']) const emit = defineEmits(['submitComment', 'load'])
...@@ -54,6 +61,9 @@ const onSubmitComment = (data: any) => { ...@@ -54,6 +61,9 @@ const onSubmitComment = (data: any) => {
<Avatar :src="data.user_info.avatar" class="publish-avatar"></Avatar> <Avatar :src="data.user_info.avatar" class="publish-avatar"></Avatar>
<div class="publish-item-hd-info"> <div class="publish-item-hd-info">
<h5>{{ data.user_info.name }}</h5> <h5>{{ data.user_info.name }}</h5>
<ul>
<li v-for="item in data.user_info.label" :key="item">{{ item }}</li>
</ul>
</div> </div>
</div> </div>
<div class="publish-item-bd"> <div class="publish-item-bd">
...@@ -71,9 +81,9 @@ const onSubmitComment = (data: any) => { ...@@ -71,9 +81,9 @@ const onSubmitComment = (data: any) => {
<div class="comment-item-hd">{{ item.user_name }}</div> <div class="comment-item-hd">{{ item.user_name }}</div>
<div class="comment-item-bd">{{ item.content }}</div> <div class="comment-item-bd">{{ item.content }}</div>
</div> </div>
<div class="comment-more" v-if="data.comments.total > data.comments.list.length" @click="$emit('load')"> <!-- <div class="comment-more" v-if="data.comments.total > data.comments.list.length" @click="viewItem">
查看{{ data.comments.total }}条评论 <van-icon name="arrow" /> 查看{{ data.comments.total }}条评论 <van-icon name="arrow" />
</div> </div> -->
</div> </div>
</div> </div>
</div> </div>
...@@ -105,8 +115,24 @@ const onSubmitComment = (data: any) => { ...@@ -105,8 +115,24 @@ const onSubmitComment = (data: any) => {
h5 { h5 {
font-size: 0.24rem; font-size: 0.24rem;
font-weight: 400; font-weight: 400;
line-height: 0.34rem;
color: #333333; color: #333333;
} }
ul {
display: flex;
}
li {
margin-top: 0.05rem;
padding: 0 0.2rem;
font-size: 0.18rem;
font-weight: 300;
line-height: 0.28rem;
color: #666666;
background: #edf6ff;
}
li + li {
margin-left: 0.1rem;
}
} }
.publish-avatar { .publish-avatar {
width: 0.68rem; width: 0.68rem;
...@@ -119,6 +145,7 @@ const onSubmitComment = (data: any) => { ...@@ -119,6 +145,7 @@ const onSubmitComment = (data: any) => {
margin-left: 0.86rem; margin-left: 0.86rem;
} }
.publish-content { .publish-content {
margin-top: 0.24rem;
font-size: 0.24rem; font-size: 0.24rem;
font-weight: 400; font-weight: 400;
line-height: 0.3rem; line-height: 0.3rem;
......
<script setup lang="ts">
import PublishItem from './PublishItem.vue'
// 详情信息
const detail = ref()
</script>
<template>
<van-popup round position="bottom" teleport="body" v-bind="$attrs">
<PublishItem :data="detail" v-bind="$attrs"></PublishItem>
</van-popup>
</template>
...@@ -6,7 +6,7 @@ defineProps<{ title?: string }>() ...@@ -6,7 +6,7 @@ defineProps<{ title?: string }>()
<div class="app-card"> <div class="app-card">
<div class="app-card-hd"> <div class="app-card-hd">
<slot name="header"> <slot name="header">
<h2 class="app-card-hd__title" v-if="title">{{ title }}</h2> <h2 class="app-card-hd__title">{{ title }}</h2>
<div class="app-card-hd-aside"> <div class="app-card-hd-aside">
<slot name="header-aside"></slot> <slot name="header-aside"></slot>
</div> </div>
......
...@@ -11,6 +11,8 @@ import Avatar from '@/components/Avatar.vue' ...@@ -11,6 +11,8 @@ import Avatar from '@/components/Avatar.vue'
import modules from './modules' import modules from './modules'
import useWXShare from '@/utils/wx'
const app = createApp(App) const app = createApp(App)
// 注册公共组件 // 注册公共组件
app.component('AppCard', AppCard).component('AppContainer', AppContainer).component('Avatar', Avatar) app.component('AppCard', AppCard).component('AppContainer', AppContainer).component('Avatar', Avatar)
...@@ -22,3 +24,5 @@ app.use(router) ...@@ -22,3 +24,5 @@ app.use(router)
app.use(Vant) app.use(Vant)
app.mount('#app') app.mount('#app')
useWXShare()
...@@ -54,5 +54,8 @@ onMounted(() => { ...@@ -54,5 +54,8 @@ onMounted(() => {
font-weight: 400; font-weight: 400;
color: #666666; color: #666666;
line-height: 0.42rem; line-height: 0.42rem;
:deep(img) {
max-width: 100%;
}
} }
</style> </style>
...@@ -14,8 +14,10 @@ defineProps<{ teams: ITeam[] }>() ...@@ -14,8 +14,10 @@ defineProps<{ teams: ITeam[] }>()
<h2>团队荣誉总榜</h2> <h2>团队荣誉总榜</h2>
<ul> <ul>
<li v-for="item in teams" :key="item.id"> <li v-for="item in teams" :key="item.id">
<h4>{{ item.name }}</h4> <router-link :to="{ name: 'teamView', params: { id: item.id } }">
<p>{{ item.slogan }}<em>|</em>{{ item.members_count }}人</p> <h4>{{ item.name }}</h4>
<p>{{ item.slogan }}<em>|</em>{{ item.members_count }}人</p>
</router-link>
</li> </li>
</ul> </ul>
</div> </div>
......
...@@ -3,13 +3,13 @@ import { ref, onMounted } from 'vue' ...@@ -3,13 +3,13 @@ import { ref, onMounted } from 'vue'
import type { HomeInfo } from '../types' import type { HomeInfo } from '../types'
import * as api from '../api' import * as api from '../api'
import Banner from '../components/Banner.vue' import Banner from '../components/Banner.vue'
// import Menu from '../components/Menu.vue' import Menu from '../components/Menu.vue'
// import AdmissionGuide from '../components/AdmissionGuide.vue' import AdmissionGuide from '../components/AdmissionGuide.vue'
import LearningMap from '../components/LearningMap.vue' import LearningMap from '../components/LearningMap.vue'
// import QueryView from '../components/QueryView.vue' import QueryView from '../components/QueryView.vue'
// import ExamStrategy from '../components/ExamStrategy.vue' import ExamStrategy from '../components/ExamStrategy.vue'
// import TeamRanking from '../components/TeamRanking.vue' import TeamRanking from '../components/TeamRanking.vue'
// import Questions from '../components/Questions.vue' import Questions from '../components/Questions.vue'
const data = ref<HomeInfo>({ const data = ref<HomeInfo>({
banner: [], banner: [],
...@@ -33,17 +33,17 @@ onMounted(() => { ...@@ -33,17 +33,17 @@ onMounted(() => {
<template> <template>
<Banner :list="data.banner"></Banner> <Banner :list="data.banner"></Banner>
<!-- <Menu></Menu> --> <Menu></Menu>
<!-- 入学指南 --> <!-- 入学指南 -->
<!-- <AdmissionGuide :docs="data.admission_guide_docs" :videos="data.admission_guide_videos"></AdmissionGuide> --> <AdmissionGuide :docs="data.admission_guide_docs" :videos="data.admission_guide_videos"></AdmissionGuide>
<!-- 学习地图 --> <!-- 学习地图 -->
<LearningMap :docs="data.learning_map_docs"></LearningMap> <LearningMap :docs="data.learning_map_docs"></LearningMap>
<!-- 权益查看 --> <!-- 权益查看 -->
<!-- <QueryView></QueryView> --> <QueryView></QueryView>
<!-- 荣誉总榜 --> <!-- 荣誉总榜 -->
<!-- <TeamRanking :teams="data.ranking"></TeamRanking> --> <TeamRanking :teams="data.ranking"></TeamRanking>
<!-- 考试攻略 --> <!-- 考试攻略 -->
<!-- <ExamStrategy :docs="data.exam_strategy_docs"></ExamStrategy> --> <ExamStrategy :docs="data.exam_strategy_docs"></ExamStrategy>
<!-- 陪伴问答 --> <!-- 陪伴问答 -->
<!-- <Questions :data="data.questions"></Questions> --> <Questions :data="data.questions"></Questions>
</template> </template>
...@@ -54,5 +54,8 @@ onMounted(() => { ...@@ -54,5 +54,8 @@ onMounted(() => {
font-weight: 400; font-weight: 400;
color: #666666; color: #666666;
line-height: 0.42rem; line-height: 0.42rem;
:deep(img) {
max-width: 100%;
}
} }
</style> </style>
...@@ -25,7 +25,7 @@ const menus: Array<{ ...@@ -25,7 +25,7 @@ const menus: Array<{
icon: 'https://webapp-pub.ezijing.com/project/prp-h5/my_menu_1.png' icon: 'https://webapp-pub.ezijing.com/project/prp-h5/my_menu_1.png'
} }
// { // {
// path: '/', // path: '/team/view/my',
// name: '我的团队', // name: '我的团队',
// icon: 'https://webapp-pub.ezijing.com/project/prp-h5/my_menu_2.png' // icon: 'https://webapp-pub.ezijing.com/project/prp-h5/my_menu_2.png'
// }, // },
......
...@@ -9,3 +9,35 @@ export function getTeamList(params?: { page?: number; page_size?: number }) { ...@@ -9,3 +9,35 @@ export function getTeamList(params?: { page?: number; page_size?: number }) {
export function createTeam(data: { name: string; slogan: string; logo: string; brief: string }) { export function createTeam(data: { name: string; slogan: string; logo: string; brief: string }) {
return httpRequest.post('/api/psp/v1/team/create-team', data) return httpRequest.post('/api/psp/v1/team/create-team', data)
} }
// 获取团队详情
export function getTeam(params: { id: string }) {
return httpRequest.get('/api/psp/v1/team/view', { params })
}
// 加入团队
export function joinTeam(data: { id: string }) {
return httpRequest.post('/api/psp/v1/team/join', data)
}
// 团队-上传资料/发布讨论
export function createTeamPosts(data: {
type: string
team_visible: string
title: string
desc: string
picture?: string
file?: string
}) {
return httpRequest.post('/api/psp/v1/team/upload', data)
}
// 团队-团队文件/讨论列表
export function getTeamFileOrQuestions(params: { id: string; type: string; page?: number; page_size?: number }) {
return httpRequest.get('/api/psp/v1/team/files-or-questions', { params })
}
// 团队-团队文件/讨论 创建评论
export function createTeamComment(data: { entity_id: string; type: string; content: string; to_comment_id?: string }) {
return httpRequest.post('/api/psp//v1/team/create-comment', data)
}
<script setup lang="ts">
import { Toast } from 'vant'
import PublishItem from '@/components/PublishItem.vue'
import { getTeamFileOrQuestions, createTeamComment } from '../api'
const props = defineProps<{ id: string }>()
// 获取列表数据
const page = ref<number>(1)
const dataset = reactive<{ total: number; list: Record<string, any>[] }>({ total: 0, list: [] })
async function fetchList(isRefresh?: boolean) {
if (isRefresh) {
page.value = 1
}
const { data } = await getTeamFileOrQuestions({ id: props.id, type: 'file', page: page.value, page_size: 20 })
dataset.total = data.total
dataset.list = isRefresh ? data.list : [...dataset.list, ...data.list]
}
onMounted(() => {
fetchList()
})
// 评论
const onSubmitComment = (data: any, action: string) => {
if (action === 'comment') {
// 评论
createTeamComment({
type: 'file',
entity_id: data.id,
content: data.comment
}).then(() => {
Toast.success('评论成功')
fetchList(true)
})
} else {
// 回复
createTeamComment({
type: 'file',
entity_id: data.entity_id,
content: data.comment,
to_comment_id: data.id
}).then(() => {
Toast.success('回复成功')
fetchList(true)
})
}
}
</script>
<template>
<AppCard>
<template #header-aside>
<div class="button"><router-link :to="{ name: 'teamFilePublish', params: { id } }">上传</router-link></div>
</template>
<template v-if="dataset.list?.length">
<PublishItem
a="123"
v-for="item in dataset.list"
:data="item"
:key="item.id"
@submitComment="onSubmitComment"
></PublishItem>
</template>
<van-empty description="暂无内容" v-else />
</AppCard>
</template>
<style lang="scss" scoped>
:deep(.publish-item) {
padding: 0.24rem;
margin-bottom: 0.2rem;
background: #fff;
border-radius: 0.2rem;
}
</style>
<script setup lang="ts">
import { Toast } from 'vant'
import PublishItem from '@/components/PublishItem.vue'
import { getTeamFileOrQuestions, createTeamComment } from '../api'
const props = defineProps<{ id: string }>()
// 获取列表数据
const dataset = reactive<{ total: number; list: Record<string, any>[] }>({ total: 0, list: [] })
async function fetchList() {
const { data } = await getTeamFileOrQuestions({ id: props.id, type: 'question' })
dataset.total = data.total
dataset.list = [...dataset.list, ...data.list]
}
onMounted(() => {
fetchList()
})
// 评论
const onSubmitComment = (data: any, action: string) => {
if (action === 'comment') {
// 评论
createTeamComment({
type: 'question',
entity_id: data.id,
content: data.comment
}).then(() => {
Toast.success('评论成功')
})
} else {
// 回复
createTeamComment({
type: 'question',
entity_id: data.entity_id,
content: data.comment,
to_comment_id: data.id
}).then(() => {
Toast.success('回复成功')
})
}
}
</script>
<template>
<AppCard>
<template #header-aside>
<div class="button"><router-link :to="{ name: 'teamQuestionPublish', params: { id } }"> 发布</router-link></div>
</template>
<template v-if="dataset.list?.length">
<PublishItem
v-for="item in dataset.list"
:data="item"
:key="item.id"
@submitComment="onSubmitComment"
></PublishItem>
</template>
<van-empty description="暂无内容" v-else />
</AppCard>
</template>
<style lang="scss" scoped>
:deep(.publish-item) {
padding: 0.24rem;
margin-bottom: 0.2rem;
background: #fff;
border-radius: 0.2rem;
}
</style>
...@@ -4,7 +4,10 @@ import { getTeamList } from '../api' ...@@ -4,7 +4,10 @@ import { getTeamList } from '../api'
import type { ITeam } from '@/types' import type { ITeam } from '@/types'
let list = ref<ITeam[]>([]) const router = useRouter()
const list = ref<ITeam[]>([])
function fetchTeamList() { function fetchTeamList() {
getTeamList({ page_size: 100 }).then(res => { getTeamList({ page_size: 100 }).then(res => {
list.value = res.data.list.list list.value = res.data.list.list
...@@ -16,8 +19,8 @@ onMounted(() => { ...@@ -16,8 +19,8 @@ onMounted(() => {
</script> </script>
<template> <template>
<ul class="list-card"> <ul class="team-list">
<li v-for="(item, index) in list" :key="index"> <li v-for="(item, index) in list" :key="index" @click="router.push({ name: 'teamView', params: { id: item.id } })">
<div class="team-order"> <div class="team-order">
<div class="order">{{ index > 2 ? index + 1 : '' }}</div> <div class="order">{{ index > 2 ? index + 1 : '' }}</div>
</div> </div>
...@@ -29,8 +32,8 @@ onMounted(() => { ...@@ -29,8 +32,8 @@ onMounted(() => {
</ul> </ul>
</template> </template>
<style lang="scss" scoped> <style lang="scss">
.list-card { .team-list {
background: #ffffff; background: #ffffff;
border-radius: 0.15rem; border-radius: 0.15rem;
opacity: 1; opacity: 1;
......
...@@ -6,8 +6,28 @@ export const routes: Array<RouteRecordRaw> = [ ...@@ -6,8 +6,28 @@ export const routes: Array<RouteRecordRaw> = [
path: '/team', path: '/team',
component: AppLayout, component: AppLayout,
children: [ children: [
{ path: '', component: () => import('./views/Index.vue') }, { name: 'teamList', path: '', component: () => import('./views/Index.vue') },
{ path: 'create', component: () => import('./views/Create.vue'), meta: { requireLogin: true } } {
name: 'teamCreate',
path: 'create',
component: () => import('./views/Create.vue'),
meta: { requireLogin: true }
},
{ name: 'teamView', path: 'view/:id', component: () => import('./views/View.vue'), props: true },
{
name: 'teamFilePublish',
path: 'view/:id/file/publish',
component: () => import('./views/PublishFile.vue'),
meta: { requireLogin: true },
props: true
},
{
name: 'teamQuestionPublish',
path: 'view/:id/question/publish',
component: () => import('./views/PublishQuestion.vue'),
meta: { requireLogin: true },
props: true
}
] ]
} }
] ]
...@@ -33,7 +33,7 @@ function onSubmit() { ...@@ -33,7 +33,7 @@ function onSubmit() {
:autosize="{ minHeight: 200 }" :autosize="{ minHeight: 200 }"
:rules="[{ required: true, message: '请输入团队简介' }]" :rules="[{ required: true, message: '请输入团队简介' }]"
/> />
<van-field :rules="[{ required: true, message: '请上传图片' }]"> <van-field :rules="[{ required: true, message: '请上传团队Logo' }]">
<template #input> <template #input>
<AppUpload v-model="form.logo"></AppUpload> <AppUpload v-model="form.logo"></AppUpload>
</template> </template>
......
<script setup lang="ts"> <script setup lang="ts">
import { Toast } from 'vant'
import { getTeamList } from '../api'
import TeamList from '../components/TeamList.vue' import TeamList from '../components/TeamList.vue'
const router = useRouter()
// let list = $ref<Record<string, any>[]>()
let myTeam = $ref<{ team_id: string }>()
async function fetchList() {
const { data = {} } = await getTeamList()
// list = data.list?.list || []
myTeam = data.my_team
}
onMounted(() => {
fetchList()
})
// 创建团队
function createTeam() {
if (myTeam) {
Toast.fail('您已经加入了团队')
} else {
router.push({ name: 'teamCreate' })
}
}
// 我的团队
function viewMyTeam() {
if (myTeam) {
router.push({ name: 'teamView', params: { id: myTeam.team_id } })
} else {
Toast.fail('您还没有加入任何团队')
}
}
</script> </script>
<template> <template>
<AppContainer title="团队总榜"> <AppContainer title="团队总榜">
<div class="team-header"> <div class="team-header">
<div class="btn-box"> <div class="btn-box" @click="createTeam">
<router-link to="/team/create"> <img src="https://webapp-pub.ezijing.com/project/prp-h5/team-h2.png" />
<img src="https://webapp-pub.ezijing.com/project/prp-h5/team-h2.png" /> <div class="b-text">团队创建</div>
<div class="b-text">团队创建</div>
</router-link>
</div> </div>
<div class="btn-box"> <div class="btn-box" @click="viewMyTeam">
<img src="https://webapp-pub.ezijing.com/project/prp-h5/team-h1.png" /> <img src="https://webapp-pub.ezijing.com/project/prp-h5/team-h1.png" />
<div class="b-text">我的团队</div> <div class="b-text">我的团队</div>
</div> </div>
......
<script setup lang="ts">
import { createTeamPosts } from '../api'
import AppUpload from '@/components/base/AppUpload.vue'
import { Toast } from 'vant'
const props = defineProps<{ id: string }>()
const router = useRouter()
const form = reactive({
type: 'file',
team_visible: '1',
title: '',
desc: '',
file: []
})
function onSubmit() {
const params = Object.assign({}, form, { file: JSON.stringify(form.file) })
createTeamPosts(params).then(() => {
Toast.success('上传成功')
router.push({ name: 'teamView', params: { id: props.id } })
})
}
</script>
<template>
<AppContainer title="上传资料" backgroundColor="#fff" headerAlign="center">
<van-form @submit="onSubmit">
<van-field v-model="form.title" placeholder="标题" :rules="[{ required: true, message: '请输入标题' }]" />
<van-field
v-model="form.desc"
type="textarea"
placeholder="正文"
:autosize="{ minHeight: 200 }"
:rules="[{ required: true, message: '请输入资料内容' }]"
/>
<van-field>
<template #input>
<AppUpload accept="*" v-model="form.file"></AppUpload>
</template>
</van-field>
<van-button block round native-type="submit" class="my-button">上传</van-button>
</van-form>
</AppContainer>
</template>
<style lang="scss" scoped>
:deep(.van-cell) {
padding-left: 0;
padding-right: 0;
&::after {
left: 0;
right: 0;
}
}
.my-button {
margin: 1rem 0;
}
</style>
<script setup lang="ts">
import { createTeamPosts } from '../api'
import AppUpload from '@/components/base/AppUpload.vue'
import { Toast } from 'vant'
const props = defineProps<{ id: string }>()
const router = useRouter()
const form = reactive({
type: 'question',
team_visible: '1',
title: '',
desc: '',
picture: []
})
function onSubmit() {
const params = Object.assign({}, form, { picture: JSON.stringify(form.picture) })
createTeamPosts(params).then(() => {
Toast.success('发布成功')
router.push({ name: 'teamView', params: { id: props.id } })
})
}
</script>
<template>
<AppContainer title="发布问题" backgroundColor="#fff" headerAlign="center">
<van-form @submit="onSubmit">
<van-field v-model="form.title" placeholder="标题" :rules="[{ required: true, message: '请输入标题' }]" />
<van-field
v-model="form.desc"
type="textarea"
placeholder="正文"
:autosize="{ minHeight: 200 }"
:rules="[{ required: true, message: '请输入问题内容' }]"
/>
<van-field>
<template #input>
<AppUpload v-model="form.picture"></AppUpload>
</template>
</van-field>
<van-button block round native-type="submit" class="my-button">发布</van-button>
</van-form>
</AppContainer>
</template>
<style lang="scss" scoped>
:deep(.van-cell) {
padding-left: 0;
padding-right: 0;
&::after {
left: 0;
right: 0;
}
}
.my-button {
margin: 1rem 0;
}
</style>
<script setup lang="ts">
import { Toast } from 'vant'
import FileList from '../components/FileList.vue'
import QuestionList from '../components/QuestionList.vue'
import * as api from '../api'
const props = defineProps<{ id: string }>()
const detail = ref()
// 获取详情信息
async function fetchDetailInfo() {
const { data } = await api.getTeam({ id: props.id })
detail.value = data
}
onMounted(() => {
fetchDetailInfo()
})
// 加入团队
async function joinTeam() {
await api.joinTeam({ id: props.id })
Toast.success('加入成功')
}
</script>
<template>
<AppContainer title="团队详情">
<div class="info" v-if="detail">
<div class="info-pic"><img :src="detail.team_info.logo" /></div>
<div class="info-main">
<h2>{{ detail.team_info.name }}</h2>
<h6>{{ detail.team_info.slogan }}</h6>
<p>
<span>人员数{{ detail.team_info.members_count }}</span
><span>积分数{{ detail.team_info.star }}</span>
</p>
<p>
<span>资料数{{ detail.team_info.files_count }}</span
><span>问答数{{ detail.team_info.questions_count }}</span>
</p>
<van-button round v-if="!detail.is_sign_in" @click="joinTeam">加入</van-button>
</div>
</div>
<van-tabs
shrink
color="#033974"
background="transparent"
title-active-color="#033974"
title-inactive-color="#4E4E4E"
>
<van-tab title="资料">
<FileList :id="id"></FileList>
</van-tab>
<van-tab title="问答">
<QuestionList :id="id"></QuestionList>
</van-tab>
</van-tabs>
</AppContainer>
</template>
<style lang="scss" scoped>
.info {
display: flex;
}
.info-pic {
margin-right: 0.16rem;
width: 2rem;
height: 2.4rem;
border-radius: 0.2rem;
overflow: hidden;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.info-main {
flex: 1;
overflow: hidden;
h2 {
font-size: 0.32rem;
font-weight: 500;
color: #333333;
}
h6 {
margin-top: 0.08rem;
font-size: 0.28rem;
font-weight: 400;
color: #4e4e4e;
}
p {
margin-top: 0.1rem;
font-size: 0.24rem;
color: #999999;
span + span {
margin-left: 0.2rem;
}
}
}
</style>
...@@ -52,6 +52,7 @@ httpRequest.interceptors.response.use( ...@@ -52,6 +52,7 @@ httpRequest.interceptors.response.use(
if (status === 403) { if (status === 403) {
location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(location.href)}` location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(location.href)}`
} else { } else {
Toast.fail(message)
console.error(`${status}: ${message}`) console.error(`${status}: ${message}`)
} }
} else { } else {
......
import httpRequest from './axios'
export default function useWXShare() {
httpRequest
.post('https://node-server.ezijing.com/share/getsignature', {
data: { appId: 'wx451c01d40d090d7a', url: location.href.split('#').pop() }
})
.then(result => {
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: 'wx451c01d40d090d7a', // 必填,公众号的唯一标识
timestamp: result.timestamp, // 必填,生成签名的时间戳
nonceStr: result.noncestr, // 必填,生成签名的随机串
signature: result.token, // 必填,签名
jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData'] // 必填,需要使用的JS接口列表
})
wx.ready(() => {
wx.updateAppMessageShareData({
title: 'PRP私享星球', // 分享标题
desc: '玩转【PRP系统知识 】践行【有品牌的IP】', // 分享描述
link: location.href,
imgUrl: 'https://webapp-pub.ezijing.com/upload/admin/8348532dc17af54ed9d2279ca12b055a.png'
})
wx.updateTimelineShareData({
title: 'PRP私享星球', // 分享标题
link: location.href,
imgUrl: 'https://webapp-pub.ezijing.com/upload/admin/8348532dc17af54ed9d2279ca12b055a.png'
})
})
})
}
{ {
"extends": "@vue/tsconfig/tsconfig.web.json", "extends": "@vue/tsconfig/tsconfig.web.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"], "include": ["env.d.ts", "auto-imports.d.ts", "src/**/*", "src/**/*.vue"],
"compilerOptions": { "compilerOptions": {
"allowJs": true,
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"@/*": ["./src/*"] "@/*": ["./src/*"]
......
...@@ -5,13 +5,19 @@ import { fileURLToPath, URL } from 'url' ...@@ -5,13 +5,19 @@ import { fileURLToPath, URL } from 'url'
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue' import vue from '@vitejs/plugin-vue'
import checker from 'vite-plugin-checker' import checker from 'vite-plugin-checker'
import AutoImport from 'unplugin-auto-import/vite'
export default defineConfig(({ mode }) => { export default defineConfig(({ mode }) => {
return { return {
base: mode === 'prod' ? 'https://webapp-pub.ezijing.com/website/prod/prp-h5/' : '/', base: mode === 'prod' ? 'https://webapp-pub.ezijing.com/website/prod/prp-h5/' : '/',
plugins: [ plugins: [
checker({ eslint: { lintCommand: 'eslint "./src/**/*.{vue,js,jsx,ts,tsx}"' } }), checker({ vueTsc: true, eslint: { lintCommand: 'eslint "./src/**/*.{vue,js,jsx,ts,tsx}"' } }),
vue({ reactivityTransform: true }) vue({ reactivityTransform: true }),
AutoImport({
imports: ['vue', 'vue/macros', 'vue-router', '@vueuse/core'],
dts: true,
eslintrc: { enabled: true }
})
], ],
server: { server: {
open: true, open: true,
...@@ -28,10 +34,6 @@ export default defineConfig(({ mode }) => { ...@@ -28,10 +34,6 @@ export default defineConfig(({ mode }) => {
alias: { alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)) '@': fileURLToPath(new URL('./src', import.meta.url))
} }
},
css: {
// 禁用SASS警告提醒
preprocessorOptions: { scss: { charset: false } }
} }
} }
}) })
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论