-
-
问卷列表
-
-
- 创建问卷
-
+
+
+
+
+
{{ spaceType === SpaceType.Group ? '团队空间' : '问卷' }}列表
+
+
+
+ 创建团队空间
+
+
+
+ 创建问卷
+
+
+
+
+
-
+
-
@@ -47,7 +153,8 @@ export default {
.question-list-root {
height: 100%;
background-color: #f6f7f9;
- .login-status {
+
+ .top-nav {
background: #fff;
color: #4a4c5b;
padding: 0 20px;
@@ -55,10 +162,25 @@ export default {
display: flex;
justify-content: space-between;
align-items: center;
- .logo-img {
- width: 90px;
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.04);
+ .left {
+ display: flex;
+ align-items: center;
+ width: calc(100% - 200px);
+ .logo-img {
+ width: 90px;
+ height: fit-content;
+ padding-right: 20px;
+ }
+ .el-menu {
+ width: 100%;
+ height: 56px;
+ border: none !important;
+ :deep(.el-menu-item, .is-active) {
+ border: none !important;
+ }
+ }
}
-
.login-info {
display: flex;
align-items: center;
@@ -78,28 +200,46 @@ export default {
color: #faa600;
}
}
-
- .list-content {
+ .content-wrap {
+ position: relative;
height: calc(100% - 56px);
- padding: 20px;
+ }
+ .list-content {
+ position: relative;
+ height: 100%;
+ width: 100%;
+ padding: 32px 32px 32px 232px;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ overflow: scroll;
.top {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24px;
+ .operation {
+ flex: 0 1 auto;
+ display: flex;
+ }
h2 {
font-size: 18px;
}
.create-btn {
+ background: #4a4c5b;
+ }
+ .space-btn {
+ background: $primary-color;
+ }
+ .btn {
width: 132px;
height: 32px;
display: flex;
justify-content: center;
align-items: center;
- background: #4a4c5b;
+
color: #fff;
.icon-chuangjian {
diff --git a/web/src/management/store/index.js b/web/src/management/store/index.js
index 69d22b47..c0ca999b 100644
--- a/web/src/management/store/index.js
+++ b/web/src/management/store/index.js
@@ -1,7 +1,7 @@
import { createStore } from 'vuex'
import edit from './edit'
import user from './user'
-
+import list from './list'
import actions from './actions'
import mutations from './mutations'
import state from './state'
@@ -13,6 +13,7 @@ export default createStore({
actions,
modules: {
edit,
- user
+ user,
+ list
}
})
diff --git a/web/src/management/store/list/index.js b/web/src/management/store/list/index.js
new file mode 100644
index 00000000..982745fe
--- /dev/null
+++ b/web/src/management/store/list/index.js
@@ -0,0 +1,260 @@
+import {
+ createSpace,
+ spaceList,
+ spaceDetail,
+ updateSpace,
+ spaceDelete
+} from '@/management/api/space'
+import { CODE_MAP } from '@/management/api/base'
+import { ElMessage } from 'element-plus'
+import 'element-plus/theme-chalk/src/message.scss'
+import { getSurveyList as surveyList } from '@/management/api/survey'
+import { set } from 'lodash-es'
+import { SpaceType } from '@/management/utils/types/workSpace'
+
+export default {
+ namespaced: true,
+ state: {
+ // 空间管理
+ spaceMenus: [
+ {
+ icon: 'icon-wodekongjian',
+ name: '我的空间',
+ id: SpaceType.Personal
+ },
+ {
+ icon: 'icon-tuanduikongjian',
+ name: '团队空间',
+ id: SpaceType.Group,
+ children: [
+ // {
+ // name: '小桔问卷调研团队',
+ // id: 'xxxx',
+ // }
+ ]
+ }
+ ],
+ spaceType: SpaceType.Personal,
+ workSpaceId: '',
+ spaceDetail: null,
+ teamSpaceList: [],
+ // 列表管理
+ surveyList: [],
+ surveyTotal: 0,
+ searchVal: '',
+ selectValueMap: {
+ surveyType: '',
+ 'curStatus.status': ''
+ },
+ buttonValueMap: {
+ 'curStatus.date': '',
+ createDate: -1
+ },
+ },
+ getters: {
+ listFliter(state) {
+ // const { searchVal, selectValueMap } = state
+ console.log('触发重新计算')
+ return [
+ {
+ comparator: '',
+ condition: [
+ {
+ field: 'title',
+ value: state.searchVal,
+ comparator: '$regex'
+ }
+ ]
+ },
+ {
+ comparator: '',
+ condition: [
+ {
+ field: 'curStatus.status',
+ value: state.selectValueMap['curStatus.status']
+ }
+ ]
+ },
+ {
+ comparator: '',
+ condition: [
+ {
+ field: 'surveyType',
+ value: state.selectValueMap.surveyType
+ }
+ ]
+ }
+ ]
+ },
+ listOrder(state) {
+ const { buttonValueMap } = state
+ return Object.entries(buttonValueMap)
+ .filter(([, effectValue]) => effectValue)
+ .reduce((prev, item) => {
+ const [effectKey, effectValue] = item
+ prev.push({ field: effectKey, value: effectValue })
+ return prev
+ }, [])
+ }
+ },
+ mutations: {
+ updateSpaceMenus(state, teamSpace) {
+ // 更新空间列表下的团队空间
+ set(state, 'spaceMenus[1].children', teamSpace)
+ },
+ changeSpaceType(state, spaceType) {
+ state.spaceType = spaceType
+ },
+ changeWorkSpace(state, workSpaceId) {
+ // 切换空间清除筛选条件
+ this.commit('list/reserSelectValueMap')
+ this.commit('list/reserButtonValueMap')
+ this.commit('list/setSearchVal', '')
+ state.workSpaceId = workSpaceId
+ },
+ setSpaceDetail(state, data) {
+ state.spaceDetail = data
+ },
+ setTeamSpaceList(state, data) {
+ state.teamSpaceList = data
+ },
+ setSurveyList(state, list) {
+ state.surveyList = list
+ },
+ setSurveyTotal(state, total) {
+ state.surveyTotal = total
+ },
+ setSearchVal(state, data) {
+ state.searchVal = data
+ },
+ reserSelectValueMap(state) {
+ state.selectValueMap = {
+ surveyType: '',
+ 'curStatus.status': ''
+ }
+ },
+ changeSelectValueMap(state, { key, value }) {
+ state.selectValueMap[key] = value
+ },
+ reserButtonValueMap(state) {
+ state.buttonValueMap = {
+ 'curStatus.date': '',
+ createDate: -1
+ }
+ },
+ changeButtonValueMap(state, { key, value }) {
+ state.buttonValueMap[key] = value
+ }
+ },
+ actions: {
+ async getSpaceList({ commit }) {
+ try {
+ const res = await spaceList()
+
+ if (res.code === CODE_MAP.SUCCESS) {
+ const { list } = res.data
+ const teamSpace = list.map((item) => {
+ return {
+ id: item._id,
+ name: item.name
+ }
+ })
+ commit('setTeamSpaceList', list)
+ commit('updateSpaceMenus', teamSpace)
+ } else {
+ ElMessage.error('getSpaceList' + res.errmsg)
+ }
+ } catch (err) {
+ ElMessage.error('getSpaceList' + err)
+ }
+ },
+ async addSpace({}, params) {
+ const res = await createSpace({
+ name: params.name,
+ description: params.description,
+ members: params.members
+ })
+
+ if (res.code === CODE_MAP.SUCCESS) {
+ ElMessage.success('添加成功')
+ } else {
+ ElMessage.error('createSpace code err' + res.errmsg)
+ }
+ },
+ async getSpaceDetail({ state, commit }, id) {
+ try {
+ const workspaceId = id || state.workSpaceId
+ const res = await spaceDetail(workspaceId)
+ if (res.code === CODE_MAP.SUCCESS) {
+ commit('setSpaceDetail', res.data)
+ } else {
+ ElMessage.error('getSpaceList' + res.errmsg)
+ }
+ } catch (err) {
+ ElMessage.error('getSpaceList' + err)
+ }
+ },
+ async updateSpace({}, params) {
+ const res = await updateSpace({
+ workspaceId: params._id,
+ name: params.name,
+ description: params.description,
+ members: params.members
+ })
+
+ if (res.code === CODE_MAP.SUCCESS) {
+ ElMessage.success('更新成功')
+ } else {
+ ElMessage.error(res.errmsg)
+ }
+ },
+ async deleteSpace({}, workspaceId) {
+ try {
+ const res = await spaceDelete(workspaceId)
+
+ if (res.code === CODE_MAP.SUCCESS) {
+ ElMessage.success('删除成功')
+ } else {
+ ElMessage.error(res.errmsg)
+ }
+ } catch (err) {
+ ElMessage.error(err)
+ }
+ },
+ async getSurveyList({ state, getters, commit }, payload) {
+ const filterString = JSON.stringify(
+ getters.listFliter.filter((item) => {
+ return item.condition[0].value
+ })
+ )
+ const orderString = JSON.stringify(getters.listOrder)
+ try {
+ let params = {
+ curPage: payload?.curPage || 1,
+ pageSize: payload?.pageSize || 10, // 默认一页10条
+ filter: filterString,
+ order: orderString,
+ workspaceId: state.workSpaceId
+ }
+ // if(payload?.order) {
+ // params.order = payload.order
+ // }
+ // if(payload.filter) {
+ // params.filter = payload.filter
+ // }
+ // if(payload?.workspaceId) {
+ // params.workspaceId = payload.workspaceId
+ // }
+ const res = await surveyList(params)
+ if (res.code === CODE_MAP.SUCCESS) {
+ commit('setSurveyList', res.data.data)
+ commit('setSurveyTotal', res.data.count)
+ } else {
+ ElMessage.error(res.errmsg)
+ }
+ } catch (error) {
+ ElMessage.error('getSurveyList status'+error)
+ }
+ }
+ }
+}
diff --git a/web/src/management/styles/icon.scss b/web/src/management/styles/icon.scss
index dcef1b00..95809ce5 100644
--- a/web/src/management/styles/icon.scss
+++ b/web/src/management/styles/icon.scss
@@ -1,9 +1,8 @@
@font-face {
- font-family: 'iconfont'; /* Project id 4263849 */
- src:
- url('//at.alicdn.com/t/c/font_4263849_xndlbqcha3l.woff2?t=1711101684869') format('woff2'),
- url('//at.alicdn.com/t/c/font_4263849_xndlbqcha3l.woff?t=1711101684869') format('woff'),
- url('//at.alicdn.com/t/c/font_4263849_xndlbqcha3l.ttf?t=1711101684869') format('truetype');
+ font-family: "iconfont"; /* Project id 4263849 */
+ src: url('//at.alicdn.com/t/c/font_4263849_xfsn9z31epc.woff2?t=1716556097756') format('woff2'),
+ url('//at.alicdn.com/t/c/font_4263849_xfsn9z31epc.woff?t=1716556097756') format('woff'),
+ url('//at.alicdn.com/t/c/font_4263849_xfsn9z31epc.ttf?t=1716556097756') format('truetype');
}
.iconfont {
@@ -131,3 +130,9 @@
.icon-NPSpingfen::before {
content: '\e6e7';
}
+.icon-wodekongjian::before {
+ content: '\e6ee';
+}
+.icon-tuanduikongjian::before {
+ content: '\e6ec';
+ }
\ No newline at end of file
diff --git a/web/src/management/styles/variable.scss b/web/src/management/styles/variable.scss
index 769ea4c8..93e05e3f 100644
--- a/web/src/management/styles/variable.scss
+++ b/web/src/management/styles/variable.scss
@@ -42,6 +42,7 @@ $primary-color-light: hsl(48, 100%, 97%);
$title-size: 0.32rem;
$font-size: 0.28rem;
$tip-size: 0.22rem;
+$font-color-remark: 12px;
// 使用CSS自定义属性
:root {
diff --git a/web/src/management/utils/constant.js b/web/src/management/utils/constant.js
index b3d7ab2c..e6a91af2 100644
--- a/web/src/management/utils/constant.js
+++ b/web/src/management/utils/constant.js
@@ -1,6 +1,12 @@
// 问卷操作枚举
export const QOP_MAP = {
+ ADD: 'add',
COPY: 'copy',
+ EDIT: 'edit',
+ COOPER: 'cooper'
+}
+export const ModifyType = {
+ ADD: 'add',
EDIT: 'edit'
}
export const qAbleList = ['radio', 'checkbox', 'binary-choice', 'vote']
diff --git a/web/src/management/utils/types/workSpace.ts b/web/src/management/utils/types/workSpace.ts
new file mode 100644
index 00000000..38696e7f
--- /dev/null
+++ b/web/src/management/utils/types/workSpace.ts
@@ -0,0 +1,59 @@
+export interface ListItem {
+ value: string
+ label: string
+}
+
+export interface MenuItem {
+ id: string
+ name: string
+ icon?: string
+ children?: MenuItem[]
+}
+
+export type IWorkspace = {
+ id?: string
+ name: string
+ description: string
+ members: IMember[]
+}
+export type IMember = {
+ userId: string
+ username: string
+ role: any,
+ _id?: string
+}
+
+export enum SpaceType {
+ Personal = 'personal',
+ Group = 'group',
+ Teamwork = 'teamwork'
+}
+export enum UserRole {
+ Admin = 'admin',
+ Member = 'user'
+}
+
+// 定义角色标签映射对象
+export const roleLabels: Record
= {
+ [UserRole.Admin]: '管理员',
+ [UserRole.Member]: '成员'
+}
+
+export interface ICollaborator {
+ _id?: string,
+ userId: string,
+ username: string
+ permissions: Array
+}
+
+export enum SurveyPermissions {
+ SurveyManage = 1001,
+ DataManage = 1002,
+ CollaboratorManage = 1003
+}
+// 定义协作者权限标签映射对象
+export const surveyPermissionsLabels: Record = {
+ [SurveyPermissions.SurveyManage]: '问卷管理',
+ [SurveyPermissions.DataManage]: '数据管理',
+ [SurveyPermissions.CollaboratorManage]: '协作管理'
+}
diff --git a/web/src/render/hooks/useShowInput.js b/web/src/render/hooks/useShowInput.js
index de90ab59..b6cccb20 100644
--- a/web/src/render/hooks/useShowInput.js
+++ b/web/src/render/hooks/useShowInput.js
@@ -10,7 +10,6 @@ export const useShowInput = (questionKey) => {
if (curRange.isShowInput) {
const rangeKey = `${questionKey}_${key}`
othersValue[rangeKey] = formValues[rangeKey]
-
;(curRange.othersKey = rangeKey), (curRange.othersValue = formValues[rangeKey])
if (!questionVal.toString().includes(key) && formValues[rangeKey]) {
// 如果分值被未被选中且对应的填写更多有值,则清空填写更多
diff --git a/web/tsconfig.app.json b/web/tsconfig.app.json
index 2bdf1188..972c80a1 100644
--- a/web/tsconfig.app.json
+++ b/web/tsconfig.app.json
@@ -1,6 +1,6 @@
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
- "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue", "src/**/**/*.vue"],
"exclude": ["src/**/__tests__/*"],
"compilerOptions": {
"composite": true,