lex 1 year ago
parent
commit
7ef3d2c113

+ 1 - 1
dev-dist/sw.js

@@ -82,7 +82,7 @@ define(['./workbox-5357ef54'], (function (workbox) { 'use strict';
     "revision": "3ca0b8505b4bec776b69afdba2768812"
   }, {
     "url": "index.html",
-    "revision": "0.9thjqef35d8"
+    "revision": "0.ap8mdb776f"
   }], {});
   workbox.cleanupOutdatedCaches();
   workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {

+ 3 - 1
src/components/CDatePicker/index.module.less

@@ -1,5 +1,6 @@
 .CdataWrap {
   position: relative;
+
   :global {
     .n-input {
       width: 353px;
@@ -15,6 +16,7 @@
       }
     }
   }
+
   .dateIcons {
     width: 20px;
     height: 19px;
@@ -23,4 +25,4 @@
     left: 15px;
     top: 11px;
   }
-}
+}

+ 17 - 0
src/components/layout/modals/api.ts

@@ -29,3 +29,20 @@ export const sysParamConfigPage = (params: any) => {
     // requestType: 'form'
   });
 };
+
+/**
+ * @description: 意见反馈类型
+ */
+export const getSysSuggestionTypeList = (params: object) => {
+  return request.post('/edu-app/sysSuggestionType/page', {
+    data: params
+  });
+};
+/**
+ * @description: 意见反馈列表
+ */
+export const getSysSuggestionList = (params: object) => {
+  return request.post('/edu-app/sysSuggestion/page', {
+    data: params
+  });
+};

+ 139 - 0
src/components/layout/modals/suggestion-list.module.less

@@ -0,0 +1,139 @@
+.suggestionList {
+  // height: 850px;
+  margin: 32px 0;
+  // height: 850px;
+}
+
+// .attendClass {
+//   margin: 32px 0;
+//   height: 850px;
+// }
+
+.attendClassSearch {
+  width: 100%;
+  display: flex;
+  align-items: center;
+  gap: 0 24px;
+  margin-bottom: 28px;
+  padding: 0 40px;
+
+  :global {
+
+    .n-select {
+      max-width: 280px;
+    }
+
+    .n-base-selection {
+      // .n-input {
+      // height: 52px;
+      // min-height: 52px;
+      height: 43px;
+      line-height: 43px;
+      --n-height: 43px !important;
+      font-size: 18px;
+      border-radius: 8px !important;
+
+    }
+
+    .n-input {
+      font-size: 18px !important;
+    }
+  }
+
+  .iconSearch {
+    width: 16px;
+    height: 17px;
+  }
+}
+
+.classList {
+  max-height: 60vh;
+  min-height: 60vh;
+  padding: 0 40px;
+
+  .listSection {
+    min-height: 60vh;
+  }
+
+  .emptySection {
+    display: flex;
+    align-items: center;
+  }
+}
+
+.thingItem {
+  background: #FFFFFF;
+  border-radius: 7px;
+  border: 1px solid #DEDEDE;
+
+  margin-bottom: 18px;
+  padding: 17px 20px;
+  cursor: pointer;
+  transition: background-color 0.2s linear;
+
+  &:hover {
+    border: 1px solid #ccc;
+    transition: background-color 0.2s linear;
+  }
+
+  :global {
+    .n-thing-header {
+      margin-bottom: 0 !important;
+    }
+
+    .n-thing-header__title {
+      width: 100%;
+      display: flex;
+      align-items: center;
+      // justify-content: space-between;
+    }
+  }
+
+
+  .item {
+    font-size: 13Px;
+    line-height: 20Px;
+    padding-bottom: 8px;
+    word-wrap: break-word;
+    word-break: break-all;
+    color: #666;
+
+    &:last-child {
+      padding-bottom: 0;
+    }
+
+    span {
+      font-weight: 600;
+      color: #131415;
+    }
+  }
+
+  .IMageWraps {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+  }
+
+  .ShowImg {
+    margin-right: 10px;
+
+    img {
+      width: 92px;
+      height: 92px;
+    }
+  }
+
+  .itemResult {
+    margin-top: 12px;
+    background: #E2F1FF;
+    border-radius: 7px;
+    padding: 12px 10px;
+    font-size: 13Px;
+    color: #1380EC;
+    line-height: 18px;
+
+    span {
+      font-weight: 600;
+    }
+  }
+}

+ 189 - 0
src/components/layout/modals/suggestion-list.tsx

@@ -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>
+    );
+  }
+});

+ 14 - 0
src/components/layout/modals/suggestion-option.module.less

@@ -284,6 +284,7 @@
       z-index: 100;
 
       .formTitle {
+        position: relative;
         text-align: center;
         margin-top: 31px;
       }
@@ -414,3 +415,16 @@
     }
   }
 }
+
+
+.suggestionBtn {
+  position: absolute;
+  right: 30px;
+  border: 1px solid #8BC5FF;
+  background: #E4F2FF !important;
+  height: 28Px;
+  font-size: 13Px;
+  font-weight: 600;
+  color: #1C81E5;
+  line-height: 18px;
+}

+ 27 - 3
src/components/layout/modals/suggestion-option.tsx

@@ -11,7 +11,8 @@ import {
   NUpload,
   UploadFileInfo,
   NImage,
-  UploadCustomRequestOptions
+  UploadCustomRequestOptions,
+  NModal
 } from 'naive-ui';
 import { useUserStore } from '/src/store/modules/users';
 import bgLine from '../images/bg-line.png';
@@ -31,6 +32,7 @@ import {
 } from '../modals/api';
 import { nextTick } from 'process';
 import { getUploadSign, onFileUpload } from '/src/helpers/oss-file-upload';
+import SuggestionList from './suggestion-list';
 
 export default defineComponent({
   name: 'train-update',
@@ -49,6 +51,7 @@ export default defineComponent({
     const state = reactive([]) as any;
     const isubmit = ref(false);
 
+    const showSuggestion = ref(false);
     const suggestionTypeList = ref([] as any);
     const ossUploadUrl = `https://gyt.ks3-cn-beijing.ksyuncs.com/`;
     const uploadRef = ref();
@@ -196,7 +199,7 @@ export default defineComponent({
     const getTypeList = async () => {
       try {
         const res = await getSuggestionList({ rows: 9999, page: 1 });
-        suggestionTypeList.value = res.data.rows;
+        suggestionTypeList.value = res.data.rows || [];
       } catch (e) {
         console.log(e);
       }
@@ -261,7 +264,18 @@ export default defineComponent({
                 emit('close');
               }}></NImage>
             <NImage class={styles.bgLine} src={bgLine} previewDisabled></NImage>
-            <h2 class={styles.formTitle}>意见反馈</h2>
+            <h2 class={styles.formTitle}>
+              意见反馈
+              <NButton
+                type="primary"
+                round
+                secondary
+                class={styles.suggestionBtn}
+                onClick={() => (showSuggestion.value = true)}>
+                反馈记录
+              </NButton>
+            </h2>
+
             <div class={styles.formWrapInfo}>
               <NForm
                 labelAlign="right"
@@ -395,6 +409,16 @@ export default defineComponent({
             </>
           ) : null}
         </div>
+
+        <NModal
+          v-model:show={showSuggestion.value}
+          class={['modalTitle background']}
+          title={'反馈记录'}
+          preset="card"
+          closeOnEsc={false}
+          style={{ width: '758px' }}>
+          <SuggestionList typeList={suggestionTypeList.value} />
+        </NModal>
       </div>
     );
   }

+ 2 - 2
vite.config.ts

@@ -23,8 +23,8 @@ function resolve(dir: string) {
 }
 // https://vitejs.dev/config/
 // https://github.com/vitejs/vite/issues/1930 .env
-// const proxyUrl = 'https://dev.kt.colexiu.com/';
-const proxyUrl = 'https://test.lexiaoya.cn';
+const proxyUrl = 'https://dev.kt.colexiu.com/';
+// const proxyUrl = 'https://test.lexiaoya.cn';
 export default defineConfig({
   base: './',
   plugins: [