Browse Source

添加审核操作

wolyshaw 2 years ago
parent
commit
e84574cc83

+ 14 - 0
src/router/routes-teacher.ts

@@ -54,6 +54,20 @@ export default [
         }
       },
       {
+        path: '/review-list',
+        component: () => import('@/teacher/review/list'),
+        meta: {
+          title: '曲谱审核列表'
+        }
+      },
+      {
+        path: '/review/:id',
+        component: () => import('@/teacher/review/detail'),
+        meta: {
+          title: '曲谱审核详情'
+        }
+      },
+      {
         path: '/openLive',
         name: 'openLive',
         component: () => import('@/teacher/open-live/index'),

+ 12 - 8
src/student/music/music.ts

@@ -1,23 +1,27 @@
 import { orderStatus } from '@/views/order-detail/orderStatus'
 import { postMessage } from '@/helpers/native-message'
 import { Dialog } from 'vant'
+import qs from 'query-string'
 
 export const getRandomKey = () => {
   const key = '' + new Date().getTime() + Math.floor(Math.random() * 1000000)
   return key
 }
 
-export const musicBuy = (item: any, callBack?: any) => {
-  const behaviorId = localStorage.getItem('behaviorId')
+export const musicBuy = (item: any, callBack?: any, moreQuery = {}) => {
+  const behaviorId = localStorage.getItem('behaviorId') || ''
+  const url = qs.stringifyUrl({
+    url: location.origin + '/accompany',
+    query: {
+      id: item.id,
+      behaviorId,
+      ...moreQuery
+    }
+  })
   postMessage({
     api: 'openAccompanyWebView',
     content: {
-      url:
-        location.origin +
-        '/accompany?id=' +
-        item.id +
-        '&behaviorId=' +
-        behaviorId,
+      url,
       // url: 'http://192.168.3.13:3000/colexiu.html?id=' + item.id,
       orientation: 0,
       isHideTitle: true,

+ 19 - 0
src/teacher/review/detail.tsx

@@ -0,0 +1,19 @@
+import { defineComponent, reactive, ref } from 'vue'
+import { useRoute } from 'vue-router'
+import { Field, CellGroup } from 'vant'
+
+export default defineComponent({
+  name: 'ReviewListDetail',
+  setup() {
+    const data = ref({})
+    const route = useRoute()
+    return () => {
+      console.log(route.params.id, route)
+      return (
+        <CellGroup>
+          <Field value={'12321'} label="曲目名称" />
+        </CellGroup>
+      )
+    }
+  }
+})

BIN
src/teacher/review/icons/init-user-icon.png


BIN
src/teacher/review/icons/music-icon.png


+ 99 - 0
src/teacher/review/item.module.less

@@ -0,0 +1,99 @@
+.item {
+  background-color: var(--music-list-item-background-color);
+  margin: 10px 14px;
+  padding: 10px;
+  padding-bottom: 0;
+  border-radius: 9px;
+  .header {
+    display: flex;
+    align-items: center;
+    border-bottom: 1px solid var(--music-list-item-border-color);
+    padding-bottom: 12px;
+    .mate {
+      display: flex;
+      flex: 1;
+      align-items: center;
+      .icon {
+        width: 40px;
+        height: 40px;
+      }
+      .info {
+        margin-left: 14px;
+        flex: 1;
+        margin-right: 14px;
+        word-break: break-all;
+        > h4 {
+          color: var(--music-list-item-title-color);
+          font-size: 14px;
+          font-weight: 600;
+        }
+        > p {
+          color: var(--music-list-item-mate-color);
+          line-height: 17px;
+          > div {
+            margin-top: 10px;
+            > span {
+              display: inline-block;
+              padding-right: 5px;
+              width: 50%;
+              height: 15px;
+              box-sizing: border-box;
+              overflow: hidden;
+              white-space: pre;
+              text-overflow: ellipsis;
+            }
+          }
+        }
+      }
+    }
+    .btn {
+      width: 54px;
+      height: 22px;
+      font-size: 12px;
+      border-radius: 11px;
+      padding: 0;
+      border: none;
+      &.vip {
+        background-color: var(--music-list-item-vip-bg);
+        color: var(--music-list-item-vip-color);
+      }
+      &.free {
+        background-color: var(--music-list-item-free-bg);
+        color: var(--music-list-item-free-color);
+      }
+      &.charge {
+        background-color: var(--music-list-item-charge-bg);
+        color: var(--music-list-item-charge-color);
+      }
+    }
+  }
+  .footer {
+    display: flex;
+    // padding-top: 8px;
+    align-items: center;
+    justify-content: space-between;
+    .user {
+      display: flex;
+      align-items: center;
+      padding: 0 10px;
+      margin-right: 5px;
+      .userIcon {
+        width: 20px;
+        height: 20px;
+        margin-right: 8px;
+      }
+      > p {
+        margin-right: 8px;
+      }
+    }
+    .favorite {
+      font-size: 16px;
+    }
+    .tags {
+      display: flex;
+      align-items: center;
+      --van-tag-default-color: #fff1de;
+      --van-tag-text-color: #ff8c00;
+    }
+  }
+}

+ 95 - 0
src/teacher/review/item.tsx

@@ -0,0 +1,95 @@
+import { defineComponent, ref } from 'vue'
+import { Button, Icon, Image } from 'vant'
+import classNames from 'classnames'
+import MusicIcon from './icons/music-icon.png'
+import styles from './item.module.less'
+
+export const chargeTypes = {
+  CHARGE: '点播',
+  FREE: '免费',
+  VIP: 'VIP'
+}
+
+export enum auditStatus {
+  UNPASS = '拒绝',
+  DOING = '审核中',
+  PASS = '通过'
+}
+
+export enum auditStatusColor {
+  UNPASS = '#f56c6c',
+  DOING = '#909399',
+  PASS = '#67c23a'
+}
+
+export default defineComponent({
+  name: 'MusicItem',
+  props: {
+    data: {
+      type: Object,
+      default: {}
+    },
+    onClick: {
+      type: Function
+    }
+  },
+  emits: ['favorite'],
+  setup({ onClick, data }) {
+    return () => {
+      const chargeType = data.musicPrice > 0 ? 'charge' : 'free'
+      return (
+        <div
+          class={styles.item}
+          onClick={() => {
+            onClick?.(data)
+          }}
+        >
+          <header class={styles.header}>
+            <div class={styles.mate}>
+              <Image src={MusicIcon} round class={styles.icon} />
+              <div class={styles.info}>
+                <h4 class="van-multi-ellipsis--l2">{data.musicSheetName}</h4>
+                <p>
+                  <div>
+                    <span>
+                      审核状态:{' '}
+                      <b
+                        style={{
+                          color: auditStatusColor[data.auditStatus],
+                          fontWeight: 'bold'
+                        }}
+                      >
+                        {auditStatus[data.auditStatus]}
+                      </b>
+                    </span>
+                    <span>上传作者: {data.username}</span>
+                  </div>
+                  <div>
+                    <span>收费价格: {data.musicPrice}元</span>
+                    <span>审批人员: {data.auditName}</span>
+                  </div>
+                </p>
+                {/* <p>
+                  <span
+                    style={{
+                      color: auditStatusColor[data.auditStatus],
+                      fontWeight: 'bold'
+                    }}
+                  >
+                    {auditStatus[data.auditStatus]}
+                  </span>{' '}
+                  {data.username}
+                </p> */}
+              </div>
+            </div>
+            <div class={styles.buttons}>
+              <Button class={classNames(styles.btn, styles[chargeType])}>
+                {chargeTypes[chargeType.toLocaleUpperCase()]}
+              </Button>
+            </div>
+          </header>
+        </div>
+      )
+    }
+  }
+})

+ 242 - 0
src/teacher/review/list.tsx

@@ -0,0 +1,242 @@
+import { defineComponent, reactive, Ref, ref } from 'vue'
+import { Sticky, List, Popup, Field, Button, Toast } from 'vant'
+import Search from '@/components/col-search'
+import request from '@/helpers/request'
+import Item, { auditStatus, auditStatusColor } from './item'
+// import SelectTag from '../search/select-tag'
+import { useRoute, useRouter } from 'vue-router'
+import ColResult from '@/components/col-result'
+import styles from '../../student/music/list/index.module.less'
+import { getRandomKey, musicBuy } from '../../student/music/music'
+
+const noop = () => {}
+
+export default defineComponent({
+  name: 'ReviewList',
+  props: {
+    hideSearch: {
+      type: Boolean,
+      default: false
+    },
+    defauleParams: {
+      type: Object,
+      default: () => ({})
+    },
+    onItemClick: {
+      type: Function,
+      default: noop
+    },
+    teacherId: {
+      type: String || Number,
+      default: ''
+    }
+  },
+  setup({ hideSearch, defauleParams, onItemClick, teacherId }, { expose }) {
+    localStorage.setItem('behaviorId', getRandomKey())
+    const route = useRoute()
+    const router = useRouter()
+    const tempParams: any = {}
+    const query = route.query
+    if (query.version) {
+      tempParams.version = query.version || '' // 处理ios审核版本
+    }
+    const params = reactive({
+      search: (route.query.search as string) || '',
+      musicTagIds: route.query.tagids || '',
+      page: 1,
+      ...tempParams,
+      ...defauleParams
+    })
+    const data = ref<any>(null)
+    const loading = ref(false)
+    const finished = ref(false)
+    const isError = ref(false)
+    const tagVisibility = ref(false)
+
+    const onSearch = (value: string) => {
+      params.page = 1
+      params.search = value
+      data.value = null
+      FetchList()
+    }
+
+    const FetchList = async () => {
+      if (loading.value) {
+        return
+      }
+      loading.value = true
+      isError.value = false
+      try {
+        const res = await request.post('/api-admin/music/sheet/audit/list', {
+          data: {
+            ...params
+          }
+        })
+        if (data.value) {
+          let result = (data.value?.rows || []).concat(res.data.rows || [])
+          data.value.rows = result
+        }
+        data.value = data.value || res.data
+        params.page = res.data.pageNo + 1
+        finished.value = res.data.pageNo >= res.data.totalPage
+      } catch (error) {
+        isError.value = true
+      }
+      loading.value = false
+    }
+
+    const onComfirm = tags => {
+      const d = Object.values(tags).flat().filter(Boolean).join(',')
+      params.musicTagIds = d
+      params.page = 1
+      data.value = null
+      FetchList()
+      tagVisibility.value = false
+    }
+
+    expose({
+      onSearch,
+      onComfirm
+    })
+
+    const message = ref('')
+    const detail: Ref<any> = ref(null)
+    const visivle = ref(false)
+
+    const submit = async (data: any) => {
+      try {
+        await request.post('/api-admin/music/sheet/audit', {
+          body: data
+        })
+        Toast.success('提交成功')
+        visivle.value = false
+        message.value = ''
+        onSearch(params.search)
+      } catch (error) {}
+    }
+
+    return () => (
+      <>
+        <List
+          loading={loading.value}
+          finished={finished.value}
+          finished-text={
+            data.value && data.value.rows.length ? '没有更多了' : ''
+          }
+          onLoad={FetchList}
+          error={isError.value}
+        >
+          {!hideSearch && (
+            <Sticky class={styles.sticky}>
+              <Search onSearch={onSearch} />
+            </Sticky>
+          )}
+
+          {data.value && data.value.rows.length
+            ? data.value.rows.map(item => (
+                <Item
+                  data={item}
+                  onClick={() => {
+                    detail.value = {
+                      ...item
+                    }
+                    visivle.value = true
+                    console.log(item)
+                    // router.push({
+                    //   path: '/review/' + item.musicSheetId,
+                    //   state: item
+                    // })
+                  }}
+                />
+              ))
+            : !loading.value && (
+                <ColResult
+                  tips="暂无曲目"
+                  classImgSize="SMALL"
+                  btnStatus={false}
+                />
+              )}
+        </List>
+        <Popup
+          position="bottom"
+          closeable
+          style={{ minHeight: '30%' }}
+          show={!!detail.value && visivle.value}
+          onClosed={() => (detail.value = null)}
+          onClose={() => (visivle.value = false)}
+          teleport="body"
+        >
+          <Field
+            label="曲目名称"
+            readonly
+            modelValue={detail.value?.musicSheetName}
+          />
+          <Field
+            label="曲谱检查"
+            readonly
+            isLink
+            modelValue="立即查看"
+            onClick={() =>
+              musicBuy({ id: detail.value?.musicSheetId }, undefined, {
+                client: 'teacher'
+              })
+            }
+          />
+          {detail.value?.auditStatus === 'DOING' ? (
+            <>
+              <Field
+                readonly={detail.value?.auditStatus !== 'DOING'}
+                v-model={message.value}
+                rows="3"
+                clearable
+                autosize
+                label="审核理由"
+                type="textarea"
+                placeholder="请输入审核理由"
+                required={detail.value?.auditStatus === 'DOING'}
+              />
+              <div
+                style={{
+                  display: 'flex'
+                }}
+              >
+                <Button
+                  disabled={
+                    !message.value && detail.value?.auditStatus === 'DOING'
+                  }
+                  block
+                  type="danger"
+                  onClick={() =>
+                    submit({
+                      musicSheetId: detail.value?.musicSheetId,
+                      authStatus: 'UNPASS',
+                      remark: message.value
+                    })
+                  }
+                >
+                  拒绝
+                </Button>
+                <Button
+                  disabled={
+                    !message.value && detail.value?.auditStatus === 'DOING'
+                  }
+                  block
+                  type="primary"
+                  onClick={() =>
+                    submit({
+                      musicSheetId: detail.value?.musicSheetId,
+                      authStatus: 'PASS',
+                      remark: message.value
+                    })
+                  }
+                >
+                  同意
+                </Button>
+              </div>
+            </>
+          ) : null}
+        </Popup>
+      </>
+    )
+  }
+})

+ 4 - 0
vite.config.ts

@@ -68,6 +68,10 @@ export default defineConfig({
         target: proxyUrl,
         changeOrigin: true
       },
+      '/api-admin': {
+        target: proxyUrl,
+        changeOrigin: true
+      },
       '/music': {
         target: proxyUrl,
         changeOrigin: true