|
@@ -0,0 +1,189 @@
|
|
|
+import { PropType, defineComponent, onMounted, reactive, ref } from 'vue';
|
|
|
+import styles from './suggestion-list.module.less';
|
|
|
+import {
|
|
|
+ NInput,
|
|
|
+ NSelect,
|
|
|
+ NScrollbar,
|
|
|
+ NSpin,
|
|
|
+ NThing,
|
|
|
+ NImageGroup,
|
|
|
+ NSpace,
|
|
|
+ NImage,
|
|
|
+ NButton
|
|
|
+} from 'naive-ui';
|
|
|
+import { getSysSuggestionList } from './api';
|
|
|
+import CDatePicker from '../../CDatePicker';
|
|
|
+import TheEmpty from '../../TheEmpty';
|
|
|
+import { useDebounceFn, useThrottleFn } from '@vueuse/core';
|
|
|
+import { getTimes } from '/src/utils';
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: 'suggestion-list',
|
|
|
+ props: {
|
|
|
+ typeList: {
|
|
|
+ type: Array as PropType<any[]>,
|
|
|
+ default: () => []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ setup(props) {
|
|
|
+ const state = reactive({
|
|
|
+ suggestionTypeList: [] as any,
|
|
|
+ loading: false,
|
|
|
+ finshed: false, // 是否加载完
|
|
|
+ pagination: {
|
|
|
+ page: 1,
|
|
|
+ rows: 20
|
|
|
+ },
|
|
|
+ searchGroup: {
|
|
|
+ keyword: null,
|
|
|
+ timer: null as any
|
|
|
+ },
|
|
|
+ tableList: [] as any,
|
|
|
+ show: false,
|
|
|
+ item: {} as any
|
|
|
+ });
|
|
|
+
|
|
|
+ const getList = async () => {
|
|
|
+ try {
|
|
|
+ if (state.pagination.page === 1) {
|
|
|
+ state.loading = true;
|
|
|
+ }
|
|
|
+ const { timer, ...res } = state.searchGroup;
|
|
|
+ const { data } = await getSysSuggestionList({
|
|
|
+ ...state.searchGroup,
|
|
|
+ ...res,
|
|
|
+ ...getTimes(timer, ['startTime', 'endTime'])
|
|
|
+ });
|
|
|
+ state.loading = false;
|
|
|
+ const tempRows = data.rows || [];
|
|
|
+ tempRows.forEach((row: any) => {
|
|
|
+ const imgList =
|
|
|
+ (row.attachmentUrls && row.attachmentUrls.split(',')) || [];
|
|
|
+ row.imgList = imgList;
|
|
|
+ });
|
|
|
+ if (state.pagination.page === 1) {
|
|
|
+ state.tableList = tempRows;
|
|
|
+ } else {
|
|
|
+ state.tableList.push(...tempRows);
|
|
|
+ }
|
|
|
+ state.finshed = data.pages <= data.current ? true : false;
|
|
|
+ } catch {
|
|
|
+ state.loading = false;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const throttledFnSearch = useDebounceFn(item => {
|
|
|
+ state.pagination.page = state.pagination.page + 1;
|
|
|
+ state.pagination.page = 1;
|
|
|
+ state.tableList = [];
|
|
|
+ state.searchGroup = Object.assign(state.searchGroup, item);
|
|
|
+ getList();
|
|
|
+ }, 100);
|
|
|
+
|
|
|
+ const throttledFn = useThrottleFn(() => {
|
|
|
+ state.pagination.page = state.pagination.page + 1;
|
|
|
+ getList();
|
|
|
+ }, 500);
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ props.typeList.forEach((item: any) => {
|
|
|
+ state.suggestionTypeList.push({
|
|
|
+ label: item.name,
|
|
|
+ value: item.id
|
|
|
+ });
|
|
|
+ });
|
|
|
+ getList();
|
|
|
+ });
|
|
|
+ return () => (
|
|
|
+ <div class={styles.suggestionList}>
|
|
|
+ <div class={styles.attendClassSearch}>
|
|
|
+ <NSelect
|
|
|
+ placeholder="反馈类型"
|
|
|
+ clearable
|
|
|
+ options={
|
|
|
+ [
|
|
|
+ { label: '反馈类型', value: null },
|
|
|
+ ...state.suggestionTypeList
|
|
|
+ ] as any
|
|
|
+ }
|
|
|
+ v-model:value={state.searchGroup.keyword}
|
|
|
+ />
|
|
|
+ <CDatePicker
|
|
|
+ v-model:value={state.searchGroup.timer}
|
|
|
+ separator={'至'}
|
|
|
+ start-placeholder="反馈开始日期"
|
|
|
+ end-placeholder="反馈结束日期"
|
|
|
+ type="daterange"
|
|
|
+ clearable={true}
|
|
|
+ timerValue={state.searchGroup.timer}></CDatePicker>
|
|
|
+
|
|
|
+ <NButton type="primary" class="searchBtn" onClick={throttledFnSearch}>
|
|
|
+ 搜索
|
|
|
+ </NButton>
|
|
|
+ </div>
|
|
|
+ <NScrollbar
|
|
|
+ class={styles.classList}
|
|
|
+ onScroll={(e: any) => {
|
|
|
+ const clientHeight = e.target?.clientHeight;
|
|
|
+ const scrollTop = e.target?.scrollTop;
|
|
|
+ const scrollHeight = e.target?.scrollHeight;
|
|
|
+ // 是否到底,是否加载完
|
|
|
+ if (
|
|
|
+ clientHeight + scrollTop + 20 >= scrollHeight &&
|
|
|
+ !state.finshed &&
|
|
|
+ !state.loading
|
|
|
+ ) {
|
|
|
+ throttledFn();
|
|
|
+ }
|
|
|
+ }}>
|
|
|
+ <NSpin show={state.loading}>
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ styles.listSection,
|
|
|
+ !state.loading && state.tableList.length <= 0
|
|
|
+ ? styles.emptySection
|
|
|
+ : ''
|
|
|
+ ]}>
|
|
|
+ {state.tableList.map((item: any) => (
|
|
|
+ <div>
|
|
|
+ <NThing class={[styles.thingItem, 'isFull']}>
|
|
|
+ <div class={styles.item}>
|
|
|
+ <span>反馈类型:</span>
|
|
|
+ {item.suggestionTypeName}
|
|
|
+ </div>
|
|
|
+ <div class={styles.item}>
|
|
|
+ <span>反馈内容:</span>
|
|
|
+ {item.content}
|
|
|
+ </div>
|
|
|
+ {item.imgList && item.imgList.length > 0 && (
|
|
|
+ <div class={styles.item}>
|
|
|
+ <NImageGroup class={styles.IMageWraps}>
|
|
|
+ {item.imgList?.map((item: any, index: number) => (
|
|
|
+ <NImage
|
|
|
+ class={[styles.ShowImg]}
|
|
|
+ src={item}
|
|
|
+ objectFit="cover"></NImage>
|
|
|
+ ))}
|
|
|
+ </NImageGroup>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+
|
|
|
+ {item.handleStatus && (
|
|
|
+ <div class={styles.itemResult}>
|
|
|
+ <span>处理结果:</span>
|
|
|
+ {item.handleAttitude === 'NO'
|
|
|
+ ? '感谢你对音乐数字课堂的关注与支持,我们会认真处理您的反馈,尽快修复和完善相关功能!'
|
|
|
+ : item.feedbackContent}
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </NThing>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ {!state.loading && state.tableList.length <= 0 && <TheEmpty />}
|
|
|
+ </div>
|
|
|
+ </NSpin>
|
|
|
+ </NScrollbar>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+});
|