Ver código fonte

完成已审核内容

yuanmingze 4 meses atrás
pai
commit
7aa9afb642

+ 3 - 0
.eslintignore

@@ -0,0 +1,3 @@
+node_modules/
+dist/
+src/**/*

+ 2 - 2
env/.env.development

@@ -2,12 +2,12 @@ NODE_ENV=development
 
 # pre环境
 # VITE_APP_URL=https://mic.freerr.cn
-# VITE_APP_URL=http://10.144.62.235:9999
+VITE_APP_URL=http://10.144.62.235:9999
 # 生产
 # VITE_APP_URL=https://cnbg.yaoyi.net
 # VITE_APP_URL=https://mic.cnbg.com.cn
 # 中生测试
-VITE_APP_URL=https://mic-t.cnbg.com.cn
+# VITE_APP_URL=https://mic-t.cnbg.com.cn
 
 
 

+ 8 - 1
src/pages-sub-admin/serviceManagement/taskList.ts

@@ -24,11 +24,18 @@ export default [
     img: 'https://yy-cloud-oss.oss-cn-beijing.aliyuncs.com/img/jpdc.png'
   },
   {
-    title: '服务审核',
+    title: '服务审核',
     color: '#8E3F3B',
     role: [4],
     url: '/pages-sub-service-mangement/taskReportapproval/index',
     backgroundColor: 'linear-gradient(94.41deg, #FFFCFC -14.28%, #F4E1E0 77.47%);',
     img: 'https://yy-cloud-oss.oss-cn-beijing.aliyuncs.com/img/kcdc.png'
+  },
+  {
+    title: '服务已审核',
+    color: '#30546E',
+    url: '/pages-sub-service-mangement/serviceReviewed/index',
+    backgroundColor: 'linear-gradient(270.93deg, #D6EDFD 0.8%, #F1F9FF 100%);',
+    img: 'https://yy-cloud-oss.oss-cn-beijing.aliyuncs.com/img/sygs.png'
   }
 ]

+ 642 - 0
src/pages-sub-service-mangement/serviceReviewed/index.vue

@@ -0,0 +1,642 @@
+<template>
+  <view class="service-reviewed">
+    <view class="reviewed-header">
+      <view class="search-content">
+        <view
+          class="search-list"
+          :class="{ current: searchParams.year }"
+          @click="searchClick('year')"
+        >
+          <text>执行包年度</text>
+          <uv-icon
+            name="arrow-down-fill"
+            :color="searchParams.year ? '#6eb657' : '#000'"
+            size="12"
+          ></uv-icon>
+        </view>
+        <view
+          class="search-list"
+          :class="{ current: searchParams.quarter }"
+          @click="searchClick('quarter')"
+        >
+          <text>执行包季度</text>
+          <uv-icon
+            name="arrow-down-fill"
+            :color="searchParams.quarter ? '#6eb657' : '#000'"
+            size="12"
+          ></uv-icon>
+        </view>
+        <view
+          class="search-list"
+          :class="{ current: searchParams.createTime }"
+          @click="searchClick('createTime')"
+        >
+          <text>服务提交时间</text>
+          <uv-icon
+            name="arrow-down-fill"
+            :color="searchParams.createTime ? '#6eb657' : '#000'"
+            size="12"
+          ></uv-icon>
+        </view>
+        <view
+          class="search-list"
+          :class="{ current: searchParams.taskTypeId }"
+          @click="searchClick('taskTypeId')"
+        >
+          <text>服务类型</text>
+          <uv-icon
+            name="arrow-down-fill"
+            :color="searchParams.taskTypeId ? '#6eb657' : '#000'"
+            size="12"
+          ></uv-icon>
+        </view>
+        <view
+          class="search-list"
+          :class="{ current: searchParams.vendorId }"
+          @click="searchClick('vendorId')"
+        >
+          <text>服务供应商</text>
+          <uv-icon
+            name="arrow-down-fill"
+            :color="searchParams.vendorId ? '#6eb657' : '#000'"
+            size="12"
+          ></uv-icon>
+        </view>
+        <view
+          class="search-list"
+          :class="{ current: searchParams.salesId }"
+          @click="searchClick('salesId')"
+        >
+          <text>代表姓名</text>
+          <uv-icon
+            name="arrow-down-fill"
+            :color="searchParams.salesId ? '#6eb657' : '#000'"
+            size="12"
+          ></uv-icon>
+        </view>
+        <view
+          class="search-list"
+          :class="{ current: searchParams.mahName }"
+          @click="searchClick('mahName')"
+        >
+          <text>产品所属生产企业</text>
+          <uv-icon
+            name="arrow-down-fill"
+            :color="searchParams.mahName ? '#6eb657' : '#000'"
+            size="12"
+          ></uv-icon>
+        </view>
+        <view
+          class="search-list"
+          :class="{ current: searchParams.skuId }"
+          @click="searchClick('skuId')"
+        >
+          <text>关联产品名称</text>
+          <uv-icon
+            name="arrow-down-fill"
+            :color="searchParams.skuId ? '#6eb657' : '#000'"
+            size="12"
+          ></uv-icon>
+        </view>
+        <view
+          class="search-list"
+          :class="{ current: searchParams.provAbbr }"
+          @click="searchClick('provAbbr')"
+        >
+          <text>执行包所属省份</text>
+          <uv-icon
+            name="arrow-down-fill"
+            :color="searchParams.provAbbr ? '#6eb657' : '#000'"
+            size="12"
+          ></uv-icon>
+        </view>
+        <view
+          class="search-list"
+          :class="{ current: searchParams.pkgIds }"
+          @click="searchClick('pkgIds')"
+        >
+          <text>上游服务部名称</text>
+          <uv-icon
+            name="arrow-down-fill"
+            :color="searchParams.pkgIds ? '#6eb657' : '#000'"
+            size="12"
+          ></uv-icon>
+        </view>
+      </view>
+      <view class="clear" @click="clearSearch">
+        <uv-icon name="close-circle" color="#000" size="24"></uv-icon>
+      </view>
+    </view>
+    <view class="list" v-if="hasInfo">
+      <view class="item" v-for="item in dataList" :key="item.id" @click="onDetail(item)">
+        <view class="top">
+          <view class="top-l">
+            <image src="@/static/images/icon/review.png" class="image" />
+            <text>{{ item.createTime }}</text>
+          </view>
+          <view class="top-r">
+            <text></text>
+            <view class="status">{{
+              item.taskStatus === '2'
+                ? '待服务商审核'
+                : item.taskStatus === '3'
+                  ? '审核通过'
+                  : item.taskStatus === '4'
+                    ? '审核拒绝'
+                    : ''
+            }}</view>
+          </view>
+        </view>
+        <view class="content">
+          <view class="title">
+            <view class="task-name">{{ getTaskName(item) }}</view>
+            <view class="score">+{{ item.taskScore }}积分</view>
+          </view>
+          <view class="item-detail">
+            <view class="num"> 任务编号:{{ item.taskNumber }} </view>
+            <view class="detail" @click.stop.self="getDetail(item)">
+              <uv-icon size="16" name="eye" color="#999"></uv-icon>
+              <text>审核详情</text>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+    <noData v-else />
+    <!-- 展示历史审核信息 -->
+    <uv-popup ref="popupRef" round="15" closeable>
+      <view class="history">
+        <view class="header">
+          <view class="title">审核详情</view>
+        </view>
+        <view class="his-list">
+          <view class="his-item" v-for="(item, index) in hisList" :key="index">
+            <view class="his-text">
+              <text class="label">审核人:</text>
+              <text>{{ item.checker }}</text>
+            </view>
+            <view class="his-text">
+              <text class="label">审核时间:</text>
+              <text>{{ item.checkTime }}</text>
+            </view>
+            <view class="his-text">
+              <text class="label">审核状态:</text>
+              <text>{{ item.checkResult }}</text>
+            </view>
+            <view class="his-text">
+              <text class="label">审核原因:</text>
+              <text>{{ item.checkMessage }}</text>
+            </view>
+          </view>
+        </view>
+      </view>
+    </uv-popup>
+    <!-- 选择器内容 -->
+    <uv-datetime-picker
+      ref="datetimeRef"
+      :mode="datetimePickerMode"
+      @confirm="confirm"
+    ></uv-datetime-picker>
+    <!-- 内容选择器 -->
+    <uv-action-sheet ref="actionSheetRef" :actions="list" @select="confirm"> </uv-action-sheet>
+
+    <!--  -->
+    <uv-picker
+      ref="pickerRef"
+      :columns="[pickerColumns]"
+      :keyName="pickerLabel"
+      @confirm="confirm"
+    ></uv-picker>
+  </view>
+</template>
+
+<script setup lang="ts">
+import {
+  getTaskV2PageCheckedApi,
+  getTaskTypeAvailApi,
+  getDeptv2Avail,
+  getTaskV2CheckHisApi,
+  getUserV2Avail,
+  getDrug2Avail,
+  getPkgV2Api
+} from '@/service/modules/serviceReviewed'
+
+import abbreviationsProvinces from '@/utils/abbreviationsProvinces'
+import { getDictByNameApi } from '@/service/modules/getDict'
+import dayjs from 'dayjs'
+import { ref, reactive, onMounted } from 'vue'
+import { onReachBottom } from '@dcloudio/uni-app'
+import noData from '@/components/noData/index.vue'
+const params = reactive({
+  currentPage: 1,
+  pageSize: 20,
+  total: 0
+})
+
+const hasInfo = ref(true)
+const dataList = ref<any[]>([])
+
+const dict = reactive({
+  taskTypeAvailArr: [],
+  deptListArr: [],
+  userListArr: [],
+  mahNameArr: [],
+  drugListArr: [],
+  currDrugList: [],
+  relPkgNameArr: [] as any[]
+})
+
+const getDictFn = () => {
+  getTaskTypeAvailApi().then((res) => (dict.taskTypeAvailArr = res.data))
+  getDeptv2Avail().then((res) => (dict.deptListArr = res.data))
+  getUserV2Avail().then((res) => (dict.userListArr = res.data))
+  getDictByNameApi('mah_name').then((res: any) => (dict.mahNameArr = res.data))
+  getDrug2Avail().then((res: any) => (dict.drugListArr = res.data))
+  getPkgV2Api().then((res) => {
+    let arr: any[] = []
+    let data = res.data
+    for (let key in data) {
+      let obj = {
+        label: key,
+        value: data[key]
+      }
+      arr.push(obj)
+    }
+    dict.relPkgNameArr = arr
+  })
+}
+const getDatalist = async () => {
+  const obj = Object.assign({
+    current: params.currentPage,
+    size: params.pageSize,
+    taskStatus: 3,
+    ...searchParams.value
+  })
+  uni.showLoading({
+    title: '正在获取数据'
+  })
+  const res = await getTaskV2PageCheckedApi(obj)
+  if (res.code === 0) {
+    params.total = res.data.total
+    dataList.value = dataList.value.concat(res.data.records)
+    hasInfo.value = !!dataList.value.length
+    uni.hideLoading()
+  }
+  uni.hideLoading()
+}
+
+const onDetail = (row: any) => {
+  console.log('rwo', row)
+
+  uni.navigateTo({
+    url: `/pages-sub-service-mangement/taskAuditDetail/index?id=${row.taskId}&type=1&show=false`
+  })
+}
+const getTaskName = (row: any) => {
+  const taskTypeId = row.taskTypeId
+  const curr: any = dict.taskTypeAvailArr.find((iten: any) => iten.id === taskTypeId)
+  return curr ? curr.name : ''
+}
+const hisList = ref<any[]>([])
+const popupRef = ref()
+
+const getDetail = async (item: any) => {
+  hisList.value = []
+  const res = await getTaskV2CheckHisApi({ taskId: item.taskId })
+  if (res.code === 0) {
+    hisList.value = res.data
+    popupRef.value.open()
+  }
+}
+
+class SearchParams {
+  year = ''
+  quarter = ''
+  createTime = ''
+  taskTypeId = ''
+  vendorId = ''
+  salesId = ''
+  mahName = ''
+  skuId = ''
+  provAbbr = ''
+  pkgIds = ''
+}
+
+const searchParams = ref(new SearchParams())
+
+const clearSearch = () => {
+  searchParams.value = new SearchParams()
+  const lastYear = dayjs().subtract(1, 'year').format('YYYY')
+  searchParams.value.year = lastYear
+  init()
+}
+
+const currType = ref('')
+const datetimeRef = ref()
+const datetimePickerMode = ref('')
+
+const list = ref<any[]>([])
+
+let quarterList = [
+  { name: '第一季度', value: '1' },
+  { name: '第二季度', value: '2' },
+  { name: '第三季度', value: '3' },
+  { name: '第四季度', value: '4' }
+]
+
+const actionSheetRef = ref()
+
+const pickerRef = ref()
+const pickerColumns = ref<any[]>([])
+const pickerLabel = ref('')
+const searchClick = (type: string) => {
+  currType.value = type
+  switch (type) {
+    case 'year':
+      datetimePickerMode.value = 'year'
+      datetimeRef.value.open()
+      break
+    case 'quarter':
+      list.value = quarterList
+      actionSheetRef.value.open()
+      break
+    case 'createTime':
+      datetimePickerMode.value = 'date'
+      datetimeRef.value.open()
+      break
+    case 'taskTypeId':
+      pickerColumns.value = dict.taskTypeAvailArr
+      pickerLabel.value = 'name'
+      pickerRef.value.open()
+      break
+    case 'vendorId':
+      pickerColumns.value = dict.deptListArr
+      pickerLabel.value = 'name'
+      pickerRef.value.open()
+      break
+    case 'salesId':
+      pickerColumns.value = dict.userListArr
+      pickerLabel.value = 'realName'
+      pickerRef.value.open()
+      break
+    case 'mahName':
+      pickerColumns.value = dict.mahNameArr
+      pickerLabel.value = 'label'
+      pickerRef.value.open()
+      break
+
+    case 'skuId':
+      // 选择关联产品 需要先选择生产企业
+      const name = searchParams.value.mahName
+      if (!name) {
+        return uni.showToast({
+          title: '请先选择生产企业',
+          icon: 'none'
+        })
+      }
+      const currList = dict.drugListArr[name]
+      dict.currDrugList = currList
+      pickerColumns.value = dict.currDrugList
+      pickerLabel.value = 'drugName'
+      pickerRef.value.open()
+      break
+    case 'provAbbr':
+      pickerColumns.value = abbreviationsProvinces
+      pickerRef.value.open()
+      break
+    case 'pkgIds':
+      pickerColumns.value = dict.relPkgNameArr
+      pickerLabel.value = 'label'
+      pickerRef.value.open()
+      break
+
+    default:
+      break
+  }
+}
+const confirm = (e: any) => {
+  switch (currType.value) {
+    case 'year':
+      searchParams.value.year = dayjs(e.value).format('YYYY')
+      break
+    case 'quarter':
+      searchParams.value.quarter = e.value
+      break
+    case 'createTime':
+      searchParams.value.createTime = dayjs(e.value).format('YYYY-MM-DD')
+      break
+    case 'taskTypeId':
+      searchParams.value.taskTypeId = e?.value[0]?.id
+      break
+    case 'vendorId':
+      searchParams.value.vendorId = e?.value[0]?.entId
+      break
+    case 'salesId':
+      searchParams.value.salesId = e?.value[0]?.userId
+      break
+    case 'mahName':
+      searchParams.value.mahName = e?.value[0]?.value
+      break
+    case 'skuId':
+      searchParams.value.skuId = e?.value[0]?.id
+      break
+    case 'provAbbr':
+      searchParams.value.provAbbr = e?.value[0]
+      break
+    case 'pkgIds':
+      searchParams.value.pkgIds = e?.value[0]
+      break
+    default:
+      break
+  }
+  init()
+}
+
+const init = () => {
+  params.currentPage = 1
+  params.total = 0
+  dataList.value = []
+  getDatalist()
+}
+
+onReachBottom(() => {
+  if (dataList.value.length === params.total) return
+  params.currentPage++
+  getDatalist()
+})
+
+onMounted(async () => {
+  const lastYear = dayjs().subtract(1, 'year').format('YYYY')
+  searchParams.value.year = lastYear
+  await getDictFn()
+  getDatalist()
+})
+</script>
+
+<style lang="scss" scoped>
+.service-reviewed {
+  padding: 0 30rpx;
+  .reviewed-header {
+    width: 690rpx;
+    height: 80rpx;
+    margin-bottom: 30rpx;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    background-color: #fff;
+    position: fixed;
+    top: 0;
+    z-index: 999;
+
+    .search-content {
+      width: 630rpx;
+      overflow-x: auto;
+      display: flex;
+      flex-wrap: nowrap;
+
+      .search-list {
+        flex: none;
+        flex-shrink: 0;
+        display: flex;
+        align-items: center;
+        padding-right: 20rpx;
+        line-height: 80rpx;
+        text {
+          margin-right: 6rpx;
+          font-weight: 600;
+        }
+      }
+      .current {
+        color: #6eb657;
+      }
+    }
+    .clear {
+      display: flex;
+      justify-content: right;
+    }
+  }
+  .list {
+    margin-top: 100rpx;
+    .item {
+      box-shadow: 0px 4rpx 4rpx 0px rgba(0, 0, 0, 0.05);
+      margin-bottom: 20rpx;
+      border-radius: 16rpx;
+      .top {
+        padding: 0 30rpx;
+        box-sizing: border-box;
+        height: 100rpx;
+        background-color: #6eb657;
+        border-top-left-radius: 16rpx;
+        border-top-right-radius: 16rpx;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        .top-l {
+          display: flex;
+          align-items: center;
+
+          .image {
+            width: 28rpx;
+            height: 28rpx;
+          }
+          text {
+            font-size: 26rpx;
+            color: #fff;
+            line-height: 36rpx;
+            margin-left: 20rpx;
+          }
+        }
+        .top-r {
+          display: flex;
+          align-items: center;
+          text {
+            display: block;
+            width: 10rpx;
+            height: 10rpx;
+            background-color: #fff;
+            border-radius: 50%;
+            margin-right: 10rpx;
+          }
+          .status {
+            color: #fff;
+            font-size: 28rpx;
+            line-height: 40rpx;
+          }
+        }
+      }
+      .content {
+        background-color: #fff;
+        padding: 30rpx;
+        box-sizing: border-box;
+        .title {
+          display: flex;
+          justify-content: space-between;
+          margin-bottom: 20rpx;
+          align-items: center;
+          .task-name {
+            font-size: 32rpx;
+            line-height: 45rpx;
+            color: #313131;
+          }
+          .score {
+            font-size: 28rpx;
+            color: #72b25b;
+          }
+        }
+        .item-detail {
+          display: flex;
+          justify-content: space-between;
+          .num {
+            font-weight: 400;
+            font-size: 20rpx;
+            line-height: 32rpx;
+            color: #999999;
+          }
+          .detail {
+            display: flex;
+            align-items: center;
+            font-size: 20rpx;
+            color: #999;
+            text {
+              margin-left: 6rpx;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+.history {
+  width: 630rpx;
+  margin: 0 auto;
+  padding: 0 30rpx;
+
+  .header {
+    text-align: center;
+    line-height: 105rpx;
+    font-size: 36rpx;
+    font-weight: 600;
+  }
+  .his-list {
+    height: 70vh;
+    overflow-y: auto;
+
+    .his-item {
+      padding: 15rpx 0;
+      border-bottom: 1px solid #eee;
+      .his-text {
+        line-height: 36rpx;
+        font-size: 22rpx;
+        text {
+          color: #333;
+        }
+        .label {
+          color: #000;
+          font-weight: 6000;
+        }
+      }
+    }
+  }
+}
+</style>

+ 7 - 0
src/pages.json

@@ -512,6 +512,13 @@
             "navigationBarTitleText": "服务审核",
             "navigationBarBackgroundColor": "#fff"
           }
+        },
+        {
+          "path": "serviceReviewed/index",
+          "style": {
+            "navigationBarTitleText": "服务已审核",
+            "onReachBottomDistance": 200
+          }
         }
       ]
     }

+ 1 - 1
src/pages/login/index.vue

@@ -169,7 +169,7 @@ async function getCode() {
     })
     const res = await getSmsCode(formData.phone)
     uni.hideLoading()
-    uni.hideLoading()
+
     if (!res.data) {
       uni.showToast({
         title: res.msg,

+ 29 - 0
src/service/modules/serviceReviewed.ts

@@ -0,0 +1,29 @@
+import http from '@/service'
+
+export function getTaskV2PageCheckedApi(params: any) {
+  return http.get('/admin/task/v2/page/checked', { params })
+}
+
+export function getTaskTypeAvailApi(params?: any) {
+  return http.get('/admin/task/type/v2/avail', { params })
+}
+
+export function getTaskV2CheckHisApi(params?: any) {
+  return http.get('/admin/task/v2/check/his', { params })
+}
+
+export function getDeptv2Avail(params?: any) {
+  return http.get('/admin/dept/v2/avail', { params })
+}
+
+export function getUserV2Avail(params?: any) {
+  return http.get('/admin/user/v2/avail', { params })
+}
+
+export function getDrug2Avail(params?: any) {
+  return http.get('/admin/drug/v2/avail', { params })
+}
+
+export function getPkgV2Api(params?: any) {
+  return http.get('/admin/pkg/avail', { params })
+}

+ 75 - 0
src/utils/abbreviationsProvinces.ts

@@ -0,0 +1,75 @@
+const provinces = [
+  '京',
+  '津',
+  '冀',
+  '晋',
+  '蒙',
+  '辽',
+  '吉',
+  '黑',
+  '沪',
+  '苏',
+  '浙',
+  '皖',
+  '闽',
+  '赣',
+  '鲁',
+  '豫',
+  '鄂',
+  '湘',
+  '粤',
+  '桂',
+  '琼',
+  '渝',
+  '川',
+  '黔',
+  '滇',
+  '藏',
+  '陕',
+  '甘',
+  '青',
+  '宁',
+  '新',
+  '港',
+  '澳',
+  '台'
+]
+
+export const provincesData = [
+  { key: '京', value: '京' },
+  { key: '津', value: '津' },
+  { key: '冀', value: '冀' },
+  { key: '晋', value: '晋' },
+  { key: '蒙', value: '蒙' },
+  { key: '辽', value: '辽' },
+  { key: '吉', value: '吉' },
+  { key: '黑', value: '黑' },
+  { key: '沪', value: '沪' },
+  { key: '苏', value: '苏' },
+  { key: '浙', value: '浙' },
+  { key: '皖', value: '皖' },
+  { key: '闽', value: '闽' },
+  { key: '赣', value: '赣' },
+  { key: '鲁', value: '鲁' },
+  { key: '豫', value: '豫' },
+  { key: '鄂', value: '鄂' },
+  { key: '湘', value: '湘' },
+  { key: '粤', value: '粤' },
+  { key: '桂', value: '桂' },
+  { key: '琼', value: '琼' },
+  { key: '渝', value: '渝' },
+  { key: '川', value: '川' },
+  { key: '黔', value: '黔' },
+  { key: '滇', value: '滇' },
+  { key: '藏', value: '藏' },
+  { key: '陕', value: '陕' },
+  { key: '甘', value: '甘' },
+  { key: '青', value: '青' },
+  { key: '宁', value: '宁' },
+  { key: '新', value: '新' },
+  { key: '港', value: '港' },
+  { key: '澳', value: '澳' },
+  { key: '台', value: '台' }
+]
+
+export default provinces

+ 3 - 1
tsconfig.json

@@ -1,6 +1,7 @@
 {
   "extends": "@vue/tsconfig/tsconfig.json",
   "compilerOptions": {
+    "noImplicitAny": false,
     "sourceMap": true,
     "module": "ESNext",
     "baseUrl": ".",
@@ -9,7 +10,8 @@
     },
     "lib": ["esnext", "dom"],
     "types": ["@dcloudio/types", "node"],
-    "ignoreDeprecations": "5.0"
+    "ignoreDeprecations": "5.0",
+    "verbatimModuleSyntax": true // 添加这一行
   },
   "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
   "exclude": ["src/wxUtils/QQMapWX.ts", "src/mp_ecard_sdk"]