Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 问卷空间协作能力 #246

Merged
merged 1 commit into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions web/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,11 @@ module.exports = {
],
parserOptions: {
ecmaVersion: 'latest'
},
rules: {
'no-empty-pattern': 'off',
"vue/multi-word-component-names": ["error", {
"ignores": ["index"]
}]
}
}
5 changes: 5 additions & 0 deletions web/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ declare module 'vue' {
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
Expand All @@ -27,6 +30,7 @@ declare module 'vue' {
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElRow: typeof import('element-plus/es')['ElRow']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSelectV2: typeof import('element-plus/es')['ElSelectV2']
ElSlider: typeof import('element-plus/es')['ElSlider']
ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTable: typeof import('element-plus/es')['ElTable']
Expand All @@ -44,6 +48,7 @@ declare module 'vue' {
IEpDelete: typeof import('~icons/ep/delete')['default']
IEpLoading: typeof import('~icons/ep/loading')['default']
IEpMinus: typeof import('~icons/ep/minus')['default']
IEpMore: typeof import('~icons/ep/more')['default']
IEpPlus: typeof import('~icons/ep/plus')['default']
IEpQuestionFilled: typeof import('~icons/ep/question-filled')['default']
IEpRank: typeof import('~icons/ep/rank')['default']
Expand Down
75 changes: 75 additions & 0 deletions web/src/management/api/space.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import axios from './base'

// 空间
export const createSpace = ({ name, description, members }: any) => {
return axios.post('/workspace', { name, description, members })
}

export const updateSpace = ({ workspaceId, name, description, members }: any) => {
return axios.post(`/workspace/${workspaceId}`, { name, description, members })
}

export const getSpaceList = () => {
return axios.get('/workspace')
}

export const getSpaceDetail = (workspaceId: string) => {
return axios.get(`/workspace/${workspaceId}`)
}

export const deleteSpace = (workspaceId: string) => {
return axios.delete(`/workspace/${workspaceId}`)
}

export const getUserList = (username: string) => {
return axios.get(`/user/getUserList`, {
params: {
username
}
})
}

// 协作权限列表
export const getPermissionList = () => {
return axios.get('collaborator/getPermissionList')
}

export const saveCollaborator = ({ surveyId, collaborators }: any) => {
return axios.post('collaborator/batchSave', {
surveyId,
collaborators
})
}

// 添加协作人
export const addCollaborator = ({ surveyId, userId, permissions }: any) => {
return axios.post('collaborator', {
surveyId,
userId,
permissions
})
}
// 更新问卷协作信息
export const updateCollaborator = ({ surveyId, userId, permissions }: any) => {
return axios.post('collaborator/changeUserPermission', {
surveyId,
userId,
permissions
})
}
// 获取问卷协作信息
export const getCollaborator = (surveyId: string) => {
return axios.get(`collaborator`, {
params: {
surveyId
}
})
}
// 获取问卷协作权限
export const getCollaboratorPermissions = (surveyId: string) => {
return axios.get(`collaborator/permissions`, {
params: {
surveyId
}
})
}
5 changes: 3 additions & 2 deletions web/src/management/api/survey.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import axios from './base'

export const getSurveyList = ({ curPage, filter, order }) => {
export const getSurveyList = ({ curPage, filter, order, workspaceId }) => {
return axios.get('/survey/getList', {
params: {
pageSize: 10,
curPage,
filter,
order
order,
workspaceId
}
})
}
Expand Down
48 changes: 41 additions & 7 deletions web/src/management/components/LeftMenu.vue
Original file line number Diff line number Diff line change
@@ -1,19 +1,40 @@
<template>
<div class="nav">
<LogoIcon />
<RouterLink v-for="(tab, index) in tabs" :key="index" class="tab-btn" :to="tab.to" replace>
<div class="icon">
<i class="iconfont" :class="tab.icon"></i>
</div>
<p>{{ tab.text }}</p>
</RouterLink>
<template v-for="(tab, index) in tabs" :key="tab.text + index">
<router-link :to="tab.to" v-slot="{ isActive }">
<div
:class="[
'tab-btn',
(['QuestionEditIndex', 'QuestionEditSetting', 'QuestionSkinSetting'].includes(
route.name
) &&
tab.to.name === 'QuestionEditIndex') ||
isActive
? 'router-link-active'
: ''
]"
>
<div class="icon">
<i class="iconfont" :class="tab.icon"></i>
</div>
<p>{{ tab.text }}</p>
</div>
</router-link>
</template>
</div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useStore } from 'vuex'
import { useRoute } from 'vue-router'
const route = useRoute()
import LogoIcon from './LogoIcon.vue'
import { SurveyPermissions } from '@/management/utils/types/workSpace.ts'
const store = useStore()

const tabs = [
const tabArr = [
{
text: '编辑问卷',
icon: 'icon-bianji',
Expand All @@ -36,6 +57,19 @@ const tabs = [
}
}
]
const tabs = ref([])
onMounted(async () => {
await store.dispatch('fetchCooperPermissions', route.params.id)
// 如果有问卷管理权限,则加入问卷编辑和投放菜单
if (store.state.cooperPermissions.includes(SurveyPermissions.SurveyManage)) {
tabs.value.push(tabArr[0])
tabs.value.push(tabArr[1])
}
// 如果有数据分析权限,则加入数据分析菜单
if (store.state.cooperPermissions.includes(SurveyPermissions.DataManage)) {
tabs.value.push(tabArr[2])
}
})
</script>
<style lang="scss" scoped>
.nav {
Expand Down
11 changes: 8 additions & 3 deletions web/src/management/pages/create/components/CreateForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
<script setup lang="ts">
import { ref, reactive, computed, toRefs } from 'vue'
import { useRouter } from 'vue-router'
import { useStore } from 'vuex'
import { ElMessage } from 'element-plus'
import 'element-plus/theme-chalk/src/message.scss'

Expand Down Expand Up @@ -78,7 +79,7 @@ const checkForm = (fn: Function) => {
}

const router = useRouter()

const store = useStore()
const submit = () => {
if (!state.canSubmit) {
return
Expand All @@ -89,10 +90,14 @@ const submit = () => {
return
}
state.canSubmit = false
const res:any = await createSurvey({
const payload: any = {
surveyType: selectType,
...state.form
})
}
if (store.state.list.workSpaceId) {
payload.workspaceId = store.state.list.workSpaceId
}
const res: any = await createSurvey(payload)
if (res?.code === 200 && res?.data?.id) {
const id = res.data.id
router.push({
Expand Down
2 changes: 1 addition & 1 deletion web/src/management/pages/create/components/NavHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const onBack = () => {

const toHomePage = () => {
router.push({
name: 'Home'
name: 'survey'
})
}
</script>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<template>
<div class="title-container">
<div
class="title"
@mouseover="showFullTitle"
@mousemove="updateTooltipPosition"
@mouseleave="hideFullTitle"
class="title"
@mouseover="showFullTitle"
@mousemove="updateTooltipPosition"
@mouseleave="hideFullTitle"
>
{{ title }}
</div>
<div
class="tooltip"
v-if="tooltipVisible"
:style="{ top: tooltipPosition.top + 'px', left: tooltipPosition.left + 'px' }"
class="tooltip"
v-if="tooltipVisible"
:style="{ top: tooltipPosition.top + 'px', left: tooltipPosition.left + 'px' }"
>
{{ title }}
</div>
Expand Down Expand Up @@ -73,5 +73,3 @@ const hideFullTitle = () => {
white-space: nowrap;
}
</style>


Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
</div>
</template>
<script setup lang="ts">
import { defineProps, computed, inject, ref, type ComputedRef } from 'vue'
import { computed, inject, ref, type ComputedRef } from 'vue'
import { ConditionNode, RuleNode } from '@/common/logicEngine/RuleBuild'
import { qAbleList } from '@/management/utils/constant.js'
import { cleanRichText } from '@/common/xss'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,18 @@ import MaterialGroup from '@/management/pages/edit/components/MaterialGroup.vue'
import { useStore } from 'vuex'
import communalLoader from '@materials/communals/communalLoader.js'

const HeaderContent = ()=>communalLoader.loadComponent('HeaderContent')
const MainTitle = ()=>communalLoader.loadComponent('MainTitle')
const SubmitButton = ()=>communalLoader.loadComponent('SubmitButton')
const LogoIcon = ()=>communalLoader.loadComponent('LogoIcon')
const HeaderContent = () => communalLoader.loadComponent('HeaderContent')
const MainTitle = () => communalLoader.loadComponent('MainTitle')
const SubmitButton = () => communalLoader.loadComponent('SubmitButton')
const LogoIcon = () => communalLoader.loadComponent('LogoIcon')

export default defineComponent({
components: {
MaterialGroup,
HeaderContent:HeaderContent(),
MainTitle:MainTitle(),
SubmitButton:SubmitButton(),
LogoIcon:LogoIcon()
HeaderContent: HeaderContent(),
MainTitle: MainTitle(),
SubmitButton: SubmitButton(),
LogoIcon: LogoIcon()
},
setup() {
const store = useStore()
Expand Down
Loading