Kaynağa Gözat

删掉不需要的页面

cxmo 9 ay önce
ebeveyn
işleme
a96359c784

+ 3 - 3
src/layout/components/HeaderWrap.vue

@@ -79,11 +79,11 @@ const hasUnRead=ref(false)//是否有未读
   right: 0;
   height: 60px;
   z-index: 50;
-  background-color: #086CE0;
+  background-color: #fff;
   box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1);
   padding: 0 30px 0 0;
   align-items: center;
-  color: #fff;
+  color: #333;
   .logo-img{
     width: 140px;
     display: block;
@@ -92,7 +92,7 @@ const hasUnRead=ref(false)//是否有未读
   }
   :deep(.el-breadcrumb__item){
     .el-breadcrumb__inner{
-      color: #fff;
+      color: #333;
     }
   }
 

+ 22 - 0
src/layout/components/LeftWrap.vue

@@ -11,6 +11,28 @@ const navList = ref([])
 
 function getNavList(){
     //mock navList
+    navList.value = [
+        {
+            Path:'/customer',
+            Name:'客户管理',
+            Children:[
+                {
+                    Path:'/customer/tempUserList',
+                    Name:'临时用户列表',
+                }
+            ]
+        },
+        {
+            Path:'/authorMgt/authorList',
+            Name:'研究员管理',
+            Children:[]
+        },
+        {
+            Path:'/customer/feedbackList',
+            Name:'客户反馈',
+            Children:[]
+        }
+    ]
     return 
   apiSystemRole.menuData().then(res=>{
     if(res.Ret===200){

+ 22 - 0
src/router/modules/author.js

@@ -0,0 +1,22 @@
+import LayoutIndex from '@/layout/Index.vue'
+
+export default[
+  {
+    path:'/authorMgt',
+    component:LayoutIndex,
+    name:'AuthorMgt',
+    meta:{
+      title:'研究员管理'
+    },
+    children:[
+      {
+        path:'authorList',
+        component:()=>import('@/views/author/List.vue'),
+        name:"AuthorList",
+        meta:{
+          title:'研究员列表'
+        },
+      },
+    ]
+  }
+]

+ 11 - 67
src/router/modules/customer.js

@@ -6,7 +6,7 @@ export default[
     component:LayoutIndex,
     name:'CustomerIndex',
     meta:{
-      title:'用户列表'
+      title:'客户管理'
     },
     children:[
       {
@@ -18,76 +18,20 @@ export default[
         }
       },
       {
-        path:'userList',
-        component:()=>import('@/views/customer/UserList.vue'),
-        name:"CustomerUserList",
+        path:'feedbackList',
+        component:()=>import('@/views/customer/FeedbackList.vue'),
+        name:'FeedbackList',
         meta:{
-          title:'基础信息'
-        },
-      },
-      {
-        path:'userAdd',
-        component:()=>import('@/views/customer/UserEdit.vue'),
-        name:"CustomerUserAdd",
-        meta:{
-          title:'新增用户',
-          from:'基础信息',
-          fromPath:'/customer/userList'
-        },
-      },
-      {
-        path:'userEdit',
-        component:()=>import('@/views/customer/UserEdit.vue'),
-        name:"CustomerUserEdit",
-        meta:{
-          title:'编辑用户',
-          from:'基础信息',
-          fromPath:'/customer/userList'
-        },
-      },
-      {
-        path:'userDetail',
-        component:()=>import('@/views/customer/UserEdit.vue'),
-        name:"CustomerUserDetail",
-        meta:{
-          title:'用户详情',
-          from:'基础信息',
-          fromPath:'/customer/userList'
-        },
-      },
-      {
-        path:'userReportStatistic',
-        component:()=>import('@/views/customer/reportStatistic/Index.vue'),
-        name:"CustomerUserReportStatistic",
-        meta:{
-          title:'阅读统计'
-        },
-      },
-      {
-        path:'potentialUserList',
-        component:()=>import('@/views/customer/PotentialUserList.vue'),
-        name:"CustomerPotentialUserList",
-        meta:{
-          title:'潜在用户列表'
-        },
-      },
-      {
-        path:'userTransform',
-        component:()=>import('@/views/customer/UserEdit.vue'),
-        name:"CustomerUserTransform",
-        meta:{
-          title:'转客户',
-          from:'潜在用户列表',
-          fromPath:'/customer/potentialUserList'
-        },
+            title:'客户反馈列表'
+        }
       },
       {
-        path:'userSearch',
-        component:()=>import('@/views/customer/UserSearch.vue'),
-        name:"CustomerUserSearch",
+        path:'feedbackList',
+        component:()=>import('@/views/customer/FeedbackList.vue'),
+        name:'FeedbackList',
         meta:{
-          title:'全局检索'
-        },
+            title:'消息推送管理'
+        }
       },
     ]
   }

+ 13 - 0
src/views/author/List.vue

@@ -0,0 +1,13 @@
+<script setup>
+import { ref, reactive } from 'vue'
+</script>
+
+<template>
+    <div>
+        研究员管理
+    </div>
+</template>
+
+<style scoped lang="scss">
+
+</style>

+ 13 - 0
src/views/customer/FeedbackList.vue

@@ -0,0 +1,13 @@
+<script setup>
+import { ref, reactive } from 'vue'
+</script>
+
+<template>
+    <div>
+        客户反馈列表
+    </div>
+</template>
+
+<style scoped lang="scss">
+
+</style>

+ 13 - 0
src/views/customer/NotificationList.vue

@@ -0,0 +1,13 @@
+<script setup>
+import { ref, reactive } from 'vue'
+</script>
+
+<template>
+    <div>
+        消息推送管理
+    </div>
+</template>
+
+<style scoped lang="scss">
+
+</style>

+ 0 - 221
src/views/customer/PotentialUserList.vue

@@ -1,221 +0,0 @@
-<script setup>
-import { Search } from '@element-plus/icons-vue'
-import { apiCustomerUser } from '@/api/customer'
-import { useRouter } from 'vue-router'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import EnableUser from './components/EnableUser.vue'
-import UserStatisticDetail from './reportStatistic/components/UserStatisticDetail.vue'
-
-const router = useRouter()
-
-const filterState = reactive({
-  regsiterTime: [],
-  readTime: [],
-  sortType:'',
-  sortVal:''
-})
-
-
-const tableColOpt = [
-  {
-    label: '手机号',
-    key: 'Phone'
-  },
-  {
-    label: '邮箱',
-    key: 'Email'
-  },
-  {
-    label: '注册时间',
-    key: 'RegisterTime',
-    sort: true
-  },
-  {
-    label: '最近一次阅读时间',
-    key: 'LastUpdateTime',
-    sort: true
-  },
-  {
-    label: '累计阅读次数',
-    key: 'ReadCnt',
-    sort: true,
-  },
-]
-const userList = ref([])
-const page = ref(1)
-const pageSize = ref(10)
-const tableLoading = ref(false)
-const totals = ref(0)
-async function getUserList() {
-  tableLoading.value = true
-  const res = await apiCustomerUser.potentialUserList({
-    PageSize: pageSize.value,
-    CurrentIndex: page.value,
-    KeyWord: filterState.keyword,
-    RegisterStartDate: filterState.regsiterTime ? filterState.regsiterTime[0] : '',
-    RegisterEndDate: filterState.regsiterTime ? filterState.regsiterTime[1] : '',
-    LastUpdateStartDate:filterState.readTime ? filterState.readTime[0] : '',
-    LastUpdateEndDate:filterState.readTime ? filterState.readTime[1] : '',
-    SortParam:filterState.sortType,
-    SortType:filterState.sortVal
-  })
-  tableLoading.value = false
-  if (res.Ret === 200) {
-    userList.value = res.Data.List || []
-    totals.value = res.Data.Paging.Totals
-  }
-}
-getUserList()
-function handlePageChange(e) {
-  page.value = e
-  getUserList()
-}
-function handleTableSort(e) {
-  // console.log(e);
-  const { order, prop } = e//order:"descending",prop: "RegisterTime"
-  filterState.sortType=prop
-  if(!order){
-    filterState.sortVal=''
-  }else{
-    filterState.sortVal=order==='descending'?'desc':'asc'
-  }
-  handleFilterList()
-}
-
-function handleFilterList() {
-  page.value = 1
-  getUserList()
-}
-
-
-
-function handleEditUser(e) {
-  router.push({
-    path: '/customer/userTransform',
-    query: {
-      id: e.UserId
-    }
-  })
-}
-
-const showDetail=ref(false)
-const activeUserId=ref(0)
-const activeUserName=ref('')
-function handleShowDetail(e){
-  activeUserId.value=e.UserId
-  activeUserName.value=e.RealName
-  showDetail.value=true
-}
-
-
-</script>
-
-<template>
-  <div class="potential-user-list-page">
-    <div class="flex filter-wrap">
-      <div style="width: 235px">
-        <el-date-picker
-          style="width: 235px"
-          v-model="filterState.regsiterTime"
-          type="daterange"
-          range-separator="至"
-          start-placeholder="注册时间"
-          end-placeholder="注册时间"
-          value-format="YYYY-MM-DD"
-          @change="handleFilterList"
-        />
-      </div>
-      <div style="width: 235px">
-        <el-date-picker
-          style="width: 235px"
-          v-model="filterState.readTime"
-          type="daterange"
-          range-separator="至"
-          start-placeholder="最近一次阅读时间"
-          end-placeholder="最近一次阅读时间"
-          value-format="YYYY-MM-DD"
-          @change="handleFilterList"
-        />
-      </div>
-      <el-input
-        placeholder="手机号/邮箱"
-        v-model="filterState.keyword"
-        :prefix-icon="Search"
-        clearable
-        style="max-width: 359px;margin-left:auto"
-        @input="handleFilterList"
-      />
-    </div>
-    <div class="userlist-wrap" style="margin-top: 20px">
-      <el-table
-        :data="userList"
-        border
-        highlight-current-row
-        element-loading-text="数据加载中..."
-        v-loading="tableLoading"
-        @sort-change="handleTableSort"
-      >
-        <el-table-column
-          v-for="column in tableColOpt"
-          :key="column.key"
-          :prop="column.key"
-          :label="column.label"
-          align="center"
-          :sortable="column.sort ? 'custom' : false"
-        >
-          <template v-if="column.headerTips" #header>
-            <span>{{ column.label }}</span>
-            <el-tooltip
-              class="box-item"
-              effect="dark"
-              :content="column.headerTips"
-              placement="top"
-            >
-              <el-icon style="position: relative; top: 2px"
-                ><i-ep-QuestionFilled
-              /></el-icon>
-            </el-tooltip>
-          </template>
-          <template #default="{ row }">
-            <span
-              v-if="column.key === 'Status'"
-              :style="{ color: !row.Status ? '#f00' : '' }"
-              >{{ row.Status ? "启用" : "禁用" }}</span
-            >
-            <el-button v-else-if="column.key === 'ReadCnt'&&row.ReadCnt>0" link type="primary" @click="handleShowDetail(row)">{{row.ReadCnt}}</el-button>
-            <span v-else>{{ row[column.key] }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="操作" align="center" width="200">
-          <template #default="{ row }">
-            <el-button type="primary" v-permission="'user:transform'" link @click="handleEditUser(row)"
-              >转客户</el-button
-            >
-            
-          </template>
-        </el-table-column>
-      </el-table>
-      <el-pagination
-        background
-        layout="total,prev,pager,next,jumper"
-        :current-page="page"
-        :page-size="pageSize"
-        :total="totals"
-        @current-change="handlePageChange"
-        style="margin-top: 30px; justify-content: flex-end"
-      />
-    </div>
-  </div>
-  <UserStatisticDetail v-model:show="showDetail" :userId="activeUserId" :userName="activeUserName"/>
-</template>
-
-<style lang="scss" scoped>
-.potential-user-list-page {
-  width: 100%;
-  overflow: hidden;
-  .filter-wrap {
-    flex-wrap: wrap;
-    gap: 10px;
-  }
-}
-</style>

+ 0 - 334
src/views/customer/UserEdit.vue

@@ -1,334 +0,0 @@
-<script setup>
-import { apiSystemCommon } from '@/api/system'
-import { apiCustomerUser } from '@/api/customer'
-import { isMobileNo, patternEmail } from '@/utils/common'
-import { useRoute, useRouter } from 'vue-router'
-import PermissionTable from './components/PermissionTable.vue'
-import { dayjs, ElMessageBox } from 'element-plus'
-import OperationRecord from './components/OperationRecord.vue'
-
-const route = useRoute()
-const router = useRouter()
-
-const userId = ref(route.query.id || 0)
-
-const isView = computed(() => {
-  return route.path === '/customer/userDetail'
-})
-
-const areaCodeOpts = ref([])
-function getPhoneAreaCode() {
-  apiSystemCommon.phoneAreaCode().then(res => {
-    if (res.Ret === 200) {
-      areaCodeOpts.value = res.Data || []
-    }
-  })
-}
-getPhoneAreaCode()
-
-
-
-
-const formRef = ref(null)
-const formRules = {
-  realName: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
-  phone: [{
-    required: true,
-    validator: (rule, value, callback) => {
-      if (value === '' && !formState.email) {
-        callback(new Error('手机号码和邮箱至少填一个'));
-      } else if (value && formState.areaCode === '86' && !isMobileNo(value || '')) {
-        callback(new Error('请输入正确的手机号格式'));
-      } else if (formState.areaCode !== '86' && isNaN(value?.trim())) {
-        callback(new Error('请输入正确的手机号格式'));
-      } else {
-        callback();
-      }
-    }, trigger: 'blur'
-  }],
-  email: [{
-    validator: (rule, value, callback) => {
-      if (value === '' && !formState.phone) {
-        callback(new Error('手机号码和邮箱至少填一个'));
-      } else if (value && !patternEmail.test(value)) {
-        callback(new Error('请输入正确的邮箱格式'));
-      } else {
-        callback();
-      }
-    }, trigger: 'blur'
-  }],
-  validTime: [{ required: true, message: '请选择有效期', trigger: 'change' }],
-  company: [{ required: true, message: '所属公司不能为空', trigger: 'blur' }],
-  sellerId: [{ required: true, message: '请选择销售', trigger: 'change' }],
-}
-const showPhoneVal=computed({
-  get(){
-    return formState.phone
-  },
-  set(value){
-    // formState.phone=value.replace(/\s+/g, ''); //`\s`在正则表达式中匹配的不仅仅是空格;它还匹配制表符、换行符等。如果只想替换普通的空白字符(即ASCII码中的32号字符)
-    formState.phone=value.replace(/ /g, '');
-  }
-})
-const formState = reactive({
-  realName: '',
-  areaCode: '86',
-  phone: '',
-  email: '',
-  sellerId: '',
-  validTime: '',
-  company: '',
-  isEnabled: false
-
-})
-
-
-const checkedIds = ref([])
-
-function getUserInfo() {
-  if (!userId.value) return
-  apiCustomerUser.userInfo({
-    UserId: userId.value
-  }).then(res => {
-    if (res.Ret === 200) {
-      const { Detail } = res.Data
-      formState.realName = Detail.RealName
-      formState.areaCode = Detail.AreaCode
-      formState.phone = Detail.Phone
-      formState.email = Detail.Email
-      formState.sellerId = Detail.SellerId||''
-      formState.validTime = Detail.ValidStartTime?[dayjs(Detail.ValidStartTime).format('YYYY-MM-DD'), dayjs(Detail.ValidEndTime).format('YYYY-MM-DD')]:''
-      formState.company = Detail.Company
-      formState.isEnabled = Detail.Status ? true : false
-      if(route.query.startTime){
-        formState.validTime=[route.query.startTime,route.query.endTime]
-      }
-    }
-  })
-}
-getUserInfo()
-
-
-function handleToEdit() {
-  // 关闭提示
-  formState.isEnabled=true
-  ElMessageBox.close()
-  router.replace({
-    path: '/customer/userEdit',
-    query: {
-      id: userId.value
-    }
-  })
-}
-function checkAddContent(msg) {
-  return h('p', [
-    msg,
-    h(ElButton, {
-      type: 'primary',
-      link: true,
-      onClick: handleToEdit
-    }, '跳转查看')
-  ]);
-}
-
-
-
-async function handleSave(type) {
-  await formRef.value.validate()
-  let params = {
-    RealName: formState.realName,
-    AreaCode: formState.areaCode,
-    Phone: formState.phone,
-    Email: formState.email,
-    SellerId: formState.sellerId,
-    ValidStartTime: formState.validTime?.[0],
-    ValidEndTime: formState.validTime?.[1],
-    Company: formState.company,
-    ChartPermission: checkedIds.value
-  }
-  if (userId.value) {
-    params.UserId = Number(userId.value)
-    params.IsEnabled = formState.isEnabled
-  } else {
-    // 新增用户时进行校验
-    const checkRes = await apiCustomerUser.userAddCheck({
-      AreaCode: formState.areaCode,
-      Phone: formState.phone,
-      Email: formState.email,
-    })
-    if (checkRes.Ret !== 200) return
-    if (checkRes.Data) {
-      userId.value = checkRes.Data.UserId
-      ElMessageBox.confirm(checkAddContent(checkRes.Msg),'操作提示',{
-        autofocus:false,
-      }).then(()=>{
-        // 确认则自动调用编辑保存一次用户信息
-        formState.isEnabled=true
-        handleSave()
-      }).catch(()=>{})
-      return
-    }
-  }
-  let res
-  if(route.name==='CustomerUserTransform'){
-    res=await apiCustomerUser.potentialUserEdit(params)
-  }else{
-    res = userId.value ? await apiCustomerUser.userEdit(params) : await apiCustomerUser.userAdd(params)
-  }
-  if (res.Ret !== 200) return
-  ElMessage.success(userId.value ? '编辑成功' : '新增成功')
-  router.replace('/customer/userList')
-
-}
-
-</script>
-
-<template>
-  <div class="bg-white flex customer-user-edit-page">
-    <div class="content-box">
-      <el-form
-        ref="formRef"
-        :model="formState"
-        :rules="formRules"
-        label-width="100px"
-        :disabled="isView"
-      >
-        <div class="flex form-tr-box">
-          <el-form-item label="姓名" prop="realName">
-            <el-input v-model="formState.realName" placeholder="请输入姓名" />
-          </el-form-item>
-          <el-form-item label="手机号" prop="phone">
-            <el-select
-              v-model="formState.areaCode"
-              placeholder="请选择"
-              style="width: 35%"
-            >
-              <el-option
-                v-for="item in areaCodeOpts"
-                :key="item.Value"
-                :label="item.Name"
-                :value="item.Value"
-              />
-            </el-select>
-            <el-input
-              v-model="showPhoneVal"
-              placeholder="手机号和邮箱至少填一个"
-              style="width: 60%; margin-left: 5%"
-            />
-          </el-form-item>
-        </div>
-        <div class="flex form-tr-box">
-          <el-form-item label="邮箱" prop="email">
-            <el-input v-model="formState.email" placeholder="请输入邮箱" />
-          </el-form-item>
-          <el-form-item label="营业部/销售" prop="sellerId">
-            <all-user-for-depart
-              style="width: 100%"
-              :props="{
-                emitPath: false,
-              }"
-              onlySelectUser
-              v-model="formState.sellerId"
-              placeholder="请选择营业部/销售"
-            />
-          </el-form-item>
-        </div>
-        <div class="flex form-tr-box">
-          <el-form-item label="有效期" prop="validTime">
-            <el-date-picker
-              style="width: 235px"
-              v-model="formState.validTime"
-              type="daterange"
-              range-separator="至"
-              start-placeholder="选择日期"
-              end-placeholder="选择日期"
-              value-format="YYYY-MM-DD"
-            />
-          </el-form-item>
-          <el-form-item label="所属公司" prop="company">
-            <el-input
-              v-model="formState.company"
-              placeholder="请输入所属公司"
-            />
-          </el-form-item>
-        </div>
-        <div class="form-tr-box auth-box">
-          <div class="auth-box-label">
-            <span class="text">权限</span>
-            <span v-if="$route.path !== '/customer/userAdd'">
-              <span style="color: var(--el-color-danger)">*</span>
-              <span>用户状态</span>
-              <el-switch
-                v-model="formState.isEnabled"
-                style="margin-left: 5px"
-              />
-            </span>
-          </div>
-
-          <PermissionTable
-            :userId="$route.query.id"
-            v-model:checkedIds="checkedIds"
-          />
-        </div>
-      </el-form>
-    </div>
-    <div class="right-box">
-      <div style="text-align: right" v-if="!isView">
-        <el-button type="primary" style="width: 120px" @click="handleSave"
-          >保存</el-button
-        >
-        <el-button
-          type="primary"
-          plain
-          @click="router.replace('/customer/userList')"
-          style="width: 120px"
-          >取消</el-button
-        >
-      </div>
-      <!-- 操作记录 -->
-      <OperationRecord />
-    </div>
-  </div>
-</template>
-
-<style lang="scss" scoped>
-.customer-user-edit-page {
-  padding: 20px;
-}
-.content-box {
-  --el-switch-off-color: #333 !important;
-  --el-switch-on-color: #333 !important;
-  flex: 1;
-  margin-right: 30px;
-  .form-tr-box {
-    gap: 0 50px;
-    margin-bottom: 20px;
-    .el-form-item {
-      width: 45%;
-      max-width: 400px;
-    }
-  }
-  .auth-box {
-    .auth-box-label {
-      max-width: 850px;
-      display: flex;
-      justify-content: space-between;
-      .text {
-        display: inline-block;
-        width: 100px;
-        text-align: right;
-        padding-right: 12px;
-        &::before {
-          content: "*";
-          color: var(--el-color-danger);
-          margin-right: 4px;
-          display: inline-block;
-        }
-      }
-    }
-  }
-}
-.right-box {
-  width: 350px;
-}
-</style>

+ 0 - 405
src/views/customer/UserList.vue

@@ -1,405 +0,0 @@
-<script setup>
-import { Search, Plus } from '@element-plus/icons-vue'
-import { apiCustomerUser } from '@/api/customer'
-import { useRouter } from 'vue-router'
-import { ElMessage, ElMessageBox,dayjs } from 'element-plus'
-import EnableUser from './components/EnableUser.vue'
-
-const router = useRouter()
-
-const filterState = reactive({
-  keyword: '',
-  seller: '',
-  status: '',
-  register: '',
-  subscribe: '',
-  regsiterTime: [],
-  createTime: [],
-  sortType:'',
-  sortVal:''
-})
-
-
-const tableColOpt = [
-  {
-    label: '姓名',
-    key: 'RealName'
-  },
-  {
-    label: '手机号',
-    key: 'Phone'
-  },
-  {
-    label: '邮箱',
-    key: 'Email'
-  },
-  {
-    label: '营业部/销售',
-    key: 'SellerName'
-  },
-  {
-    label: '用户状态',
-    key: 'Status',
-    width: '100px'
-  },
-  {
-    label: '有效期',
-    key: 'ValidStartTime',
-    width: '200px'
-  },
-  {
-    label: '到期时长',
-    key: 'RestDate',
-    sort: true,
-    width: '120px'
-  },
-  {
-    label: '是否注册',
-    key: 'IsRegistered',
-    width: '100px'
-  },
-  {
-    label: '注册时间',
-    key: 'RegisterTime',
-    sort: true,
-    headerTips: '用户首次登录小程序的时间'
-  },
-  {
-    label: '创建时间',
-    key: 'CreateTime',
-    sort: true,
-    headerTips: '系统中新增该用户的时间'
-  },
-  {
-    label: '是否关注公众号',
-    key: 'IsSubscribed'
-  },
-]
-const userList = ref([])
-const page = ref(1)
-const pageSize = ref(10)
-const tableLoading = ref(false)
-const totals = ref(0)
-async function getUserList() {
-  tableLoading.value = true
-  const res = await apiCustomerUser.userList({
-    PageSize: pageSize.value,
-    CurrentIndex: page.value,
-    SellerId: filterState.seller ? filterState.seller.join(',') : '',
-    Status: filterState.status,
-    KeyWord: filterState.keyword,
-    IsRegistered: filterState.register,
-    IsSubscribed: filterState.subscribe,
-    RegisterStartDate: filterState.regsiterTime ? filterState.regsiterTime[0] : '',
-    RegisterEndDate: filterState.regsiterTime ? filterState.regsiterTime[1] : '',
-    CreateStartDate: filterState.createTime ? filterState.createTime[0] : '',
-    CreateEndDate: filterState.createTime ? filterState.createTime[1] : '',
-    SortParam:filterState.sortType,
-    SortType:filterState.sortVal
-  })
-  tableLoading.value = false
-  if (res.Ret === 200) {
-    userList.value = res.Data.List || []
-    totals.value = res.Data.Paging.Totals
-  }
-}
-getUserList()
-function handlePageChange(e) {
-  page.value = e
-  getUserList()
-}
-function handleTableSort(e) {
-  // console.log(e);
-  const { order, prop } = e//order:"descending",prop: "RegisterTime"
-  filterState.sortType=prop
-  if(!order){
-    filterState.sortVal=''
-  }else{
-    filterState.sortVal=order==='descending'?'desc':'asc'
-  }
-  
-  handleFilterList()
-}
-function handleFilterList() {
-  page.value = 1
-  getUserList()
-}
-
-
-
-
-
-function handleEditUser(e) {
-  const link=router.resolve({
-    path: '/customer/userEdit',
-    query: {
-      id: e.UserId
-    }
-  }).href
-  window.open(link,'__blank')
-}
-
-// 禁用用户
-async function handleDisabledUser(row) {
-  const res = await apiCustomerUser.setUserStatus({
-    UserId: row.UserId,
-    IsEnabled: false
-  })
-  if (res.Ret !== 200) return
-  ElMessage.success('禁用成功')
-  getUserList()
-}
-
-// 启用用户
-const showEnableUserPop = ref(false)
-const enableUserId = ref(0)
-function handleEnableUser(row) {
-  enableUserId.value = row.UserId
-  showEnableUserPop.value = true
-}
-
-// 删除用户
-function handleDelUser(row) {
-  ElMessageBox.confirm(
-    '该操作会删除该用户所有相关信息,不可恢复,确认删除吗?',
-    '提示'
-  ).then(() => {
-    apiCustomerUser.userDelete({
-      UserId: row.UserId
-    }).then(res => {
-      if (res.Ret === 200) {
-        ElMessage.success('删除成功')
-        getUserList()
-      }
-
-    })
-  }).catch(() => { })
-}
-
-// 跳转详情
-function handleGoDetail(e){
-  const link=router.resolve({
-    path:'/customer/userDetail',
-    query:{
-      id:e.UserId
-    }
-  }).href
-  window.open(link,'__blank')
-}
-
-
-</script>
-
-<template>
-  <div class="customer-user-list-page">
-    <div>
-      <el-button
-        type="primary"
-        :icon="Plus"
-        @click="$router.push('/customer/userAdd')"
-        v-permission="'user:add'"
-        >新增</el-button
-      >
-      <el-input
-        placeholder="姓名/手机号/邮箱"
-        v-model="filterState.keyword"
-        :prefix-icon="Search"
-        clearable
-        style="max-width: 359px;float: right"
-        @input="handleFilterList"
-      />
-    </div>
-    <div class="flex filter-wrap">
-      <all-user-for-depart
-        style="width: 165px"
-        v-model="filterState.seller"
-        :props="{
-          emitPath: false,
-          multiple: true,
-        }"
-        clearable
-        filterable
-        @change="handleFilterList"
-      />
-      <el-select
-        placeholder="用户状态"
-        v-model="filterState.status"
-        style="width: 165px"
-        @change="handleFilterList"
-        clearable
-      >
-        <el-option label="启用" value="正式"></el-option>
-        <el-option label="禁用" value="禁用"></el-option>
-      </el-select>
-      <el-select
-        placeholder="注册状态"
-        v-model="filterState.register"
-        style="width: 165px"
-        clearable
-        @change="handleFilterList"
-      >
-        <el-option label="是" value="是"></el-option>
-        <el-option label="否" value="否"></el-option>
-      </el-select>
-      <el-select
-        placeholder="是否关注公众号"
-        v-model="filterState.subscribe"
-        style="width: 165px"
-        clearable
-        @change="handleFilterList"
-      >
-        <el-option label="是" value="是"></el-option>
-        <el-option label="否" value="否"></el-option>
-      </el-select>
-      <div style="width: 235px">
-        <el-date-picker
-          style="width: 235px"
-          v-model="filterState.regsiterTime"
-          type="daterange"
-          range-separator="至"
-          start-placeholder="注册时间"
-          end-placeholder="注册时间"
-          clearable
-          value-format="YYYY-MM-DD"
-          @change="handleFilterList"
-        />
-      </div>
-      <div style="width: 235px">
-        <el-date-picker
-          style="width: 235px"
-          v-model="filterState.createTime"
-          type="daterange"
-          range-separator="至"
-          start-placeholder="创建时间"
-          end-placeholder="创建时间"
-          value-format="YYYY-MM-DD"
-          clearable
-          @change="handleFilterList"
-        />
-      </div>
-      
-    </div>
-    <div class="userlist-wrap" style="margin-top: 20px">
-      <el-table
-        :data="userList"
-        border
-        stripe
-        highlight-current-row
-        element-loading-text="数据加载中..."
-        v-loading="tableLoading"
-        @sort-change="handleTableSort"
-        @row-click="handleGoDetail"
-      >
-        <el-table-column
-          v-for="column in tableColOpt"
-          :key="column.key"
-          :prop="column.key"
-          :label="column.label"
-          :sortable="column.sort ? 'custom' : false"
-          :width="column.width"
-        >
-          <template v-if="column.headerTips" #header>
-            <span>{{ column.label }}</span>
-            <el-tooltip
-              class="box-item"
-              effect="dark"
-              :content="column.headerTips"
-              placement="top"
-            >
-              <el-icon style="position: relative; top: 2px"
-                ><i-ep-QuestionFilled
-              /></el-icon>
-            </el-tooltip>
-          </template>
-          <template #default="{ row }">
-            <span
-              v-if="column.key === 'Status'"
-              :style="{ color: !row.Status ? '#f00' : '' }"
-              >{{ row.Status ? "启用" : "禁用" }}</span
-            >
-            <span v-else-if="column.key === 'IsRegistered'">{{
-              row.IsRegistered ? "是" : "否"
-            }}</span>
-            <span v-else-if="column.key === 'IsSubscribed'">{{
-              row.IsSubscribed ? "是" : "否"
-            }}</span>
-            <span v-else-if="column.key === 'ValidStartTime'"
-              >{{ formatTime(row.ValidStartTime, "YYYY-MM-DD") }}~{{
-                formatTime(row.ValidEndTime, "YYYY-MM-DD")
-              }}</span
-            >
-            <span v-else-if="column.key === 'RegisterTime'">{{
-              formatTime(row.RegisterTime)
-            }}</span>
-            <span v-else-if="column.key === 'CreateTime'">{{
-              formatTime(row.CreateTime)
-            }}</span>
-            <span v-else>{{ row[column.key] }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="操作" width="160">
-          <template #default="{ row }">
-            <el-button
-              v-permission="'user:edit'"
-              type="primary"
-              link
-              @click.stop="handleEditUser(row)"
-              >编辑</el-button
-            >
-            <el-button
-              v-permission="'user:editEnabled'"
-              type="danger"
-              link
-              v-if="row.Status"
-              @click.stop="handleDisabledUser(row)"
-              >禁用</el-button
-            >
-            <el-button
-              v-permission="'user:editEnabled'"
-              type="primary"
-              link
-              v-else
-              @click.stop="handleEnableUser(row)"
-              >启用</el-button
-            >
-            <el-button
-              v-permission="'user:delete'"
-              type="danger"
-              link
-              @click.stop="handleDelUser(row)"
-              >删除</el-button
-            >
-          </template>
-        </el-table-column>
-      </el-table>
-      <el-pagination
-        background
-        layout="total,prev,pager,next,jumper"
-        :current-page="page"
-        :page-size="pageSize"
-        :total="totals"
-        @current-change="handlePageChange"
-        style="margin-top: 30px; justify-content: flex-end"
-      />
-    </div>
-  </div>
-
-  <!-- 开启用户 -->
-  <EnableUser
-    v-model:show="showEnableUserPop"
-    :userId="enableUserId"
-    @success="getUserList()"
-  />
-</template>
-
-<style lang="scss" scoped>
-.customer-user-list-page {
-  width: 100%;
-  overflow: hidden;
-  .filter-wrap {
-    margin-top: 10px;
-    flex-wrap: wrap;
-    gap: 10px;
-  }
-}
-</style>

+ 0 - 294
src/views/customer/UserSearch.vue

@@ -1,294 +0,0 @@
-<script setup>
-import { Search } from '@element-plus/icons-vue'
-import { apiCustomerUser } from '@/api/customer'
-import UserStatisticDetail from './reportStatistic/components/UserStatisticDetail.vue'
-import EnableUser from './components/EnableUser.vue'
-import { useRouter } from 'vue-router'
-
-const router=useRouter()
-
-const filterState = reactive({
-  keyword: '',
-  sortType: '',
-  sortVal: ''
-})
-
-const tableColOpt = [
-  {
-    label: '姓名',
-    key: 'RealName'
-  },
-  {
-    label: '手机号',
-    key: 'Phone'
-  },
-  {
-    label: '邮箱',
-    key: 'Email'
-  },
-  {
-    label: '注册时间',
-    key: 'RegisterTime',
-    sort: true
-  },
-  {
-    label: '最近一次阅读时间',
-    key: 'LastUpdateTime',
-    sort: true
-  },
-  {
-    label: '累计阅读次数',
-    key: 'ReadCnt',
-    sort: true,
-  },
-]
-const userList = ref([])
-const page = ref(1)
-const pageSize = ref(10)
-const tableLoading = ref(false)
-const totals = ref(0)
-async function getUserList() {
-  if (!filterState.keyword) return
-  tableLoading.value = true
-  const res = await apiCustomerUser.userGlobalSearch({
-    PageSize: pageSize.value,
-    CurrentIndex: page.value,
-    KeyWord: filterState.keyword,
-    SortParam: filterState.sortType,
-    SortType: filterState.sortVal
-  })
-  tableLoading.value = false
-  if (res.Ret === 200) {
-    userList.value = res.Data.List || []
-    totals.value = res.Data.Paging.Totals
-  }
-}
-function handlePageChange(e) {
-  page.value = e
-  getUserList()
-}
-function handleTableSort(e) {
-  // console.log(e);
-  const { order, prop } = e//order:"descending",prop: "RegisterTime"
-  filterState.sortType = prop
-  if (!order) {
-    filterState.sortVal = ''
-  } else {
-    filterState.sortVal = order === 'descending' ? 'desc' : 'asc'
-  }
-
-  handleFilterList()
-}
-function handleFilterList() {
-  page.value = 1
-  totals.value = 0
-  userList.value = []
-  getUserList()
-}
-
-
-const showReadDetail = ref(false)
-const activeUserId = ref(0)
-const activeUserName = ref('')
-function handleShowReadDetail(e) {
-  activeUserId.value = e.UserId
-  activeUserName.value = e.RealName
-  showReadDetail.value = true
-}
-
-// 转客户
-function handleTransFormUser(e) {
-  router.push({
-    path: '/customer/userTransform',
-    query: {
-      id: e.UserId
-    }
-  })
-}
-
-function handleEditUser(e) {
-  const link=router.resolve({
-    path: '/customer/userEdit',
-    query: {
-      id: e.UserId
-    }
-  }).href
-  window.open(link,'__blank')
-}
-
-// 禁用用户
-async function handleDisabledUser(row) {
-  const res = await apiCustomerUser.setUserStatus({
-    UserId: row.UserId,
-    IsEnabled: false
-  })
-  if (res.Ret !== 200) return
-  ElMessage.success('禁用成功')
-  userList.value=[]
-  getUserList()
-}
-
-// 启用用户
-const showEnableUserPop = ref(false)
-const enableUserId = ref(0)
-function handleEnableUser(row) {
-  enableUserId.value = row.UserId
-  showEnableUserPop.value = true
-}
-
-// 删除用户
-function handleDelUser(row) {
-  ElMessageBox.confirm(
-    '该操作会删除该用户所有相关信息,不可恢复,确认删除吗?',
-    '提示'
-  ).then(() => {
-    apiCustomerUser.userDelete({
-      UserId: row.UserId
-    }).then(res => {
-      if (res.Ret === 200) {
-        ElMessage.success('删除成功')
-        userList.value=[]
-        getUserList()
-      }
-
-    })
-  }).catch(() => { })
-}
-
-// 跳转详情
-function handleGoDetail(e){
-  if(e.Status===1) return
-  const link=router.resolve({
-    path:'/customer/userDetail',
-    query:{
-      id:e.UserId
-    }
-  }).href
-  window.open(link,'__blank')
-}
-
-
-
-</script>
-
-<template>
-  <div class="user-search-page">
-    <el-input
-      placeholder="姓名/手机号/邮箱"
-      v-model="filterState.keyword"
-      :prefix-icon="Search"
-      clearable
-      style="max-width: 359px"
-      @change="handleFilterList"
-    />
-    <div class="userlist-wrap" style="margin-top: 20px">
-      <el-table
-        :data="userList"
-        border
-        highlight-current-row
-        element-loading-text="数据加载中..."
-        v-loading="tableLoading"
-        @sort-change="handleTableSort"
-        @row-click="handleGoDetail"
-      >
-        <el-table-column
-          v-for="column in tableColOpt"
-          :key="column.key"
-          :prop="column.key"
-          :label="column.label"
-          align="center"
-          :sortable="column.sort ? 'custom' : false"
-        >
-          <template v-if="column.headerTips" #header>
-            <span>{{ column.label }}</span>
-            <el-tooltip
-              class="box-item"
-              effect="dark"
-              :content="column.headerTips"
-              placement="top"
-            >
-              <el-icon style="position: relative; top: 2px"
-                ><i-ep-QuestionFilled
-              /></el-icon>
-            </el-tooltip>
-          </template>
-          <template #default="{ row }">
-            <el-button
-              v-if="column.key === 'ReadCnt' && row.ReadCnt > 0"
-              link
-              type="primary"
-              @click.stop="handleShowReadDetail(row)"
-              >{{ row.ReadCnt }}</el-button
-            >
-            <span v-else>{{ row[column.key] || "--" }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="操作" align="center" width="200">
-          <template #default="{ row }">
-            <!-- 潜在 -->
-            <template v-if="row.Status === 1">
-              <el-button
-                type="primary"
-                v-if="hasPermission('user:globalTransform')"
-                link
-                @click="handleTransFormUser(row)"
-                >转客户</el-button
-              >
-            </template>
-            <template v-else>
-              <el-button
-                type="primary"
-                v-if="hasPermission('user:globalEdit')"
-                link
-                @click.stop="handleEditUser(row)"
-                >编辑</el-button
-              >
-              <el-button
-                type="danger"
-                link
-                v-if="hasPermission('user:globalEnabled')&&row.Status"
-                @click.stop="handleDisabledUser(row)"
-                >禁用</el-button
-              >
-              <el-button
-                type="primary"
-                link
-                v-if="hasPermission('user:globalEnabled')&&!row.Status"
-                @click.stop="handleEnableUser(row)"
-                >启用</el-button
-              >
-              <el-button
-                type="danger"
-                v-if="hasPermission('user:globalDelete')"
-                link
-                @click.stop="handleDelUser(row)"
-                >删除</el-button
-              >
-            </template>
-          </template>
-        </el-table-column>
-      </el-table>
-      <el-pagination
-        background
-        layout="total,prev,pager,next,jumper"
-        :current-page="page"
-        :page-size="pageSize"
-        :total="totals"
-        @current-change="handlePageChange"
-        style="margin-top: 30px; justify-content: flex-end"
-      />
-    </div>
-  </div>
-  <!-- 阅读统计 -->
-  <UserStatisticDetail
-    v-model:show="showReadDetail"
-    :userId="activeUserId"
-    :userName="activeUserName"
-  />
-  <!-- 开启用户 -->
-  <EnableUser
-    v-model:show="showEnableUserPop"
-    :userId="enableUserId"
-    @success="userList.value=[];getUserList()"
-  />
-</template>

+ 0 - 149
src/views/customer/components/EnableUser.vue

@@ -1,149 +0,0 @@
-<script setup>
-import { apiCustomerUser } from '@/api/customer'
-import { dayjs, ElMessage } from 'element-plus'
-import { useRouter } from 'vue-router'
-
-const show = defineModel('show', { type: Boolean, default: false })
-
-const props = defineProps({
-  userId: {
-    type: Number,
-    default: 0
-  }
-})
-const emits=defineEmits(['success'])
-
-const router=useRouter()
-
-const userInfo = ref(null)
-const time = ref('')
-async function getData() {
-  const res = await apiCustomerUser.userInfo({
-    UserId: props.userId
-  })
-  if (res.Ret !== 200) return
-  userInfo.value = res.Data
-  time.value = [dayjs(res.Data.Detail.ValidStartTime).format('YYYY-MM-DD'), dayjs(res.Data.Detail.ValidEndTime).format('YYYY-MM-DD')]
-}
-
-function handleSave(){
-  const isEnd=dayjs()
-  const params={
-    UserId:props.userId,
-    IsEnabled:true,
-    ValidStartTime:time.value[0],
-    ValidEndTime:time.value[1]
-  }
-  if(dayjs().isAfter(params.ValidEndTime,'day')){
-    ElMessage.error('有效期已到期,请重新设置')
-    return
-  }
-  apiCustomerUser.setUserStatus(params).then(res=>{
-    if(res.Ret===200){
-      ElMessage.success('启用成功')
-      emits('success')
-      show.value=false
-    }
-  })
-}
-
-
-watch(
-  () => show.value,
-  (n) => {
-    if (n) {
-      getData()
-    }
-  }
-)
-
-function goEdit(){
-  router.push({
-    path:'/customer/userEdit',
-    query:{
-      id:props.userId,
-      startTime:time.value[0],
-      endTime:time.value[1]
-    }
-  })
-}
-
-</script>
-
-<template>
-  <el-dialog v-model="show" width="700" title="操作提示" draggable>
-    <div class="user-info-wrap" v-if="userInfo">
-      <div class="item-box">
-        <span class="label">姓名</span>
-        <span>{{ userInfo.Detail.RealName }}</span>
-      </div>
-      <div class="item-box">
-        <span class="label">有效期</span>
-        <div>
-          <el-date-picker
-            style="width: 235px"
-            v-model="time"
-            type="daterange"
-            range-separator="~"
-            start-placeholder="开始时间"
-            end-placeholder="结束时间"
-            size="large"
-            :clearable="false"
-            :editable="false"
-            value-format="YYYY-MM-DD"
-          />
-        </div>
-      </div>
-      <div class="item-box">
-        <span class="label">权限</span>
-        <div @click="goEdit">
-          <svg-icon
-            name="edit"
-            size="18px"
-            style="position: relative; top: 3px"
-          ></svg-icon>
-          <span class="edit-text">去编辑</span>
-        </div>
-      </div>
-      <div
-        class="item-box"
-        v-for="(value, key) in userInfo.Permission"
-        :key="key"
-      >
-        <span class="label">{{ key }}</span>
-        <div style="flex: 1; gap: 5px;flex-wrap:wrap" class="flex">
-          <el-tag type="primary" v-for="v in value" :key="v">{{ v }}</el-tag>
-        </div>
-      </div>
-    </div>
-    <div style="text-align: center">
-      <el-button type="primary" plain size="large" @click="show = false"
-        >取消</el-button
-      >
-      <el-button type="primary" size="large" @click="handleSave"
-        >保存</el-button
-      >
-    </div>
-  </el-dialog>
-</template>
-
-<style lang="scss" scoped>
-.user-info-wrap {
-  .item-box {
-    display: flex;
-    align-items: center;
-    overflow: hidden;
-    margin-bottom: 20px;
-    .label {
-      flex-shrink: 0;
-      width: 100px;
-      text-align: right;
-      margin-right: 20px;
-    }
-    .edit-text {
-      color: var(--el-primary-color);
-      cursor: pointer;
-    }
-  }
-}
-</style>

+ 0 - 46
src/views/customer/components/OperationRecord.vue

@@ -1,46 +0,0 @@
-<script setup>
-import { apiCustomerUser } from '@/api/customer'
-import { useRoute } from 'vue-router'
-import { dayjs } from 'element-plus'
-
-const route = useRoute()
-
-const list = ref([])
-function getRecord() {
-  if(!route.query.id&&['/customer/userTransform','/customer/userAdd'].includes(route.path)) return
-  apiCustomerUser.userOperationRecord({
-    UserId: route.query.id
-  }).then(res => {
-    if (res.Ret !== 200) return
-    list.value = res.Data.List || []
-  })
-}
-getRecord()
-
-</script>
-
-<template>
-  <div class="customer-operationRecord-wrap" v-if="list.length>0">
-    <el-timeline>
-      <el-timeline-item
-        v-for="item in list"
-        :key="item.UserChangeRecordId"
-        :timestamp="dayjs(item.CreateTime).format('YYYY-MM-DD HH:mm:ss')"
-        color="#4099ef"
-      >
-        {{ item.Content }}
-      </el-timeline-item>
-    </el-timeline>
-  </div>
-</template>
-
-<style lang="scss" scoped>
-.customer-operationRecord-wrap {
-  margin-top: 20px;
-  max-width: 350px;
-  max-height: 90vh;
-  overflow-y: auto;
-  padding: 20px;
-  border: 1px solid #dcdfe6;
-}
-</style>

+ 0 - 207
src/views/customer/components/PermissionTable.vue

@@ -1,207 +0,0 @@
-<script setup>
-import { apiCustomerUser } from '@/api/customer'
-import { watch } from 'vue'
-
-const props = defineProps({
-  userId: {
-    type: [Number, String],
-    default: ''
-  }
-})
-
-const checkedIds = defineModel('checkedIds', { type: Array, default: [] })
-
-const opts = ref([])
-async function getAuthData() {
-  const res = await apiCustomerUser.userPermissionData({
-    UserId: props.userId || ''
-  })
-  if (res.Ret !== 200) return
-  opts.value = res.Data.List || []
-  const selectArr = res.Data.SelectedList || []
-  if (selectArr.length === 0) {
-    opts.value.forEach(item => {
-      item.PublicChild && item.PublicChild.forEach(_i => {
-        checkedIds.value.push(_i.ChartPermissionId)
-      })
-    });
-  } else {
-    checkedIds.value = res.Data.SelectedList
-  }
-
-}
-getAuthData()
-
-// 二级品种选中态改变
-function handleSelectChange(checked, item) {
-  console.log('二级品种选中态改变');
-  if (checked) {
-    checkedIds.value.push(item.ChartPermissionId)
-  } else {
-    checkedIds.value = checkedIds.value.filter(i => i !== item.ChartPermissionId)
-  }
-}
-
-// 一级品种选中态改变
-function handleChangeLevel1(checked, item) {
-  console.log('一级品种选中态改变');
-  if (checked) {
-    item.PrivateChild && item.PrivateChild.forEach(_i => {
-      if (!checkedIds.value.includes(_i.ChartPermissionId)) {
-        checkedIds.value.push(_i.ChartPermissionId)
-      }
-    })
-  } else {
-    //取消全选
-    let ids = []
-    item.PrivateChild && item.PrivateChild.forEach(_e => {
-      ids.push(_e.ChartPermissionId)
-    })
-    checkedIds.value = checkedIds.value.filter(_e => !ids.includes(_e))
-  }
-}
-
-// 控制一级品种的状态 0全没选中 1部分选中 2全选中
-function level1Status(item) {
-  let allCount = 0//一级品种总共有多少二级
-  let count = 0//当前有多少该一级品种下面的二级是选中的
-  if (item.PublicChild) {
-    allCount = allCount + item.PublicChild.length
-    count = count + item.PublicChild.length //公有的都选中
-  }
-  if (item.PrivateChild) {
-    allCount = allCount + item.PrivateChild.length
-    item.PrivateChild.forEach(_i => {
-      if (checkedIds.value.includes(_i.ChartPermissionId)) {
-        count++
-      }
-    })
-  }
-
-  if (count === 0) {//全没选中
-    return 0
-  } else if (count === allCount) {//全选中了
-    return 2
-  } else {//部分选中
-    return 1
-  }
-}
-
-//全选状态 0全没选中 1部分选中 2全选中
-const allSelectStatus = computed(() => {
-
-  let count = 0 //总共有多少二级品种
-  opts.value.forEach(item => {
-    if (item.PublicChild) {
-      count = count + item.PublicChild.length
-    }
-    if (item.PrivateChild) {
-      count = count + item.PrivateChild.length
-    }
-  })
-
-  if (checkedIds.value.length === 0) return 0
-  if (checkedIds.value.length > 0 && checkedIds.value.length < count) return 1
-  if (checkedIds.value.length === count) return 2
-})
-
-// 全选状态改变
-function handleChangeAll(checked) {
-  let arr=[]
-  opts.value.forEach(item => {
-    item.PublicChild?.forEach(_i=>{
-      arr.push(_i.ChartPermissionId)
-    })
-    if (checked){//权限将所有私有权限选中
-      item.PrivateChild?.forEach(_i=>{
-        arr.push(_i.ChartPermissionId)
-      })
-    }
-  })
-  checkedIds.value=arr
-}
-
-</script>
-
-<template>
-  <div class="permission-table-wrap">
-    <div class="item-wrap">
-      <div class="checkall-box">
-        <el-checkbox
-          :model-value="allSelectStatus === 2"
-          :indeterminate="allSelectStatus === 1"
-          @change="handleChangeAll"
-          >全选</el-checkbox
-        >
-      </div>
-    </div>
-    <div
-      class="item-wrap"
-      v-for="level1 in opts"
-      :key="level1.ChartPermissionId"
-    >
-      <div class="checkall-box">
-        <el-checkbox
-          @change="handleChangeLevel1($event, level1)"
-          :model-value="level1Status(level1) === 2"
-          :indeterminate="level1Status(level1) === 1"
-          >{{ level1.PermissionName }}</el-checkbox
-        >
-      </div>
-      <!-- 公有权限 -->
-      <div class="child-box" v-if="level1.PublicChild">
-        <span class="label-tag pub-tag">公有</span>
-        <el-checkbox
-          :model-value="checkedIds.includes(pubitem.ChartPermissionId)"
-          disabled
-          v-for="pubitem in level1.PublicChild"
-          :key="pubitem.ChartPermissionId"
-          >{{ pubitem.PermissionName }}</el-checkbox
-        >
-      </div>
-      <!-- 私有权限 -->
-      <div class="child-box" v-if="level1.PrivateChild">
-        <span class="label-tag pri-tag">私有</span>
-        <el-checkbox
-          :model-value="checkedIds.includes(priitem.ChartPermissionId)"
-          v-for="priitem in level1.PrivateChild"
-          :key="priitem.ChartPermissionId"
-          @change="handleSelectChange($event, priitem)"
-          >{{ priitem.PermissionName }}</el-checkbox
-        >
-      </div>
-    </div>
-  </div>
-</template>
-
-<style lang="scss" scoped>
-.permission-table-wrap {
-  margin-top: 10px;
-  margin-left: 60px;
-  border: 1px solid #ebeff6;
-  .item-wrap {
-    border-bottom: 1px solid #ebeff6;
-    .checkall-box {
-      border-bottom: 1px solid #ebeff6;
-      padding: 14px 16px;
-      background-color: #f9faff;
-    }
-    .child-box {
-      padding: 14px 16px;
-      .label-tag {
-        display: inline-block;
-        padding: 2px 3px;
-        margin-right: 10px;
-      }
-      .pub-tag {
-        color: #436cff;
-        background-color: #d1e4ff;
-      }
-      .pri-tag {
-        color: #edab29;
-        background-color: #fffaeb;
-      }
-    }
-  }
-}
-</style>

+ 0 - 95
src/views/customer/reportStatistic/Chart.vue

@@ -1,95 +0,0 @@
-<script setup>
-import { Switch } from '@element-plus/icons-vue'
-import { apiCustomerUser } from '@/api/customer'
-import LineChart from './components/LineChart.vue'
-import PieChart from './components/PieChart.vue'
-
-
-const emits = defineEmits(['change'])
-
-const filterState = reactive({
-  type: '',
-  keyword: ''
-})
-
-const userId = ref('')
-const options = ref([])
-const searchLoading = ref(false)
-async function handleSearch(query) {
-  if (query) {
-    searchLoading.value = true
-    const res = await apiCustomerUser.userList({
-      PageSize: 100,
-      CurrentIndex: 1,
-      KeyWord: query
-    })
-    searchLoading.value = false
-    if (res.Ret === 200) {
-      const arr = res.Data.List || []
-      options.value = arr
-    } else {
-      options.value = []
-    }
-  }
-}
-
-
-
-</script>
-
-<template>
-  <div class="user-report-statistic-chart-page">
-    <div class="flex filter-wrap">
-      <el-button
-        type="primary"
-        :icon="Switch"
-        link
-        @click="emits('change', 'chart')"
-        >数据表</el-button
-      >
-      <el-select
-        v-model="userId"
-        filterable
-        remote
-        placeholder="姓名/手机号/邮箱"
-        :remote-method="handleSearch"
-        :loading="searchLoading"
-        style="max-width: 359px; margin-left: auto"
-        clearable
-      >
-        <template #prefix>
-          <el-icon><i-ep-Search /></el-icon>
-        </template>
-
-        <el-option
-          v-for="item in options"
-          :key="item.UserId"
-          :label="item.RealName"
-          :value="item.UserId"
-        />
-      </el-select>
-    </div>
-    <div class="content-wrap">
-      <div class="bg-white item-wrap">
-        <LineChart :userId="userId"/>
-      </div>
-      <div class="bg-white item-wrap">
-        <PieChart :userId="userId"/>
-      </div>
-    </div>
-  </div>
-</template>
-
-<style lang="scss" scoped>
-.filter-wrap {
-  gap: 10px;
-}
-.content-wrap {
-  display: flex;
-  gap: 0 30px;
-  .item-wrap {
-    margin-top: 20px;
-    flex: 1;
-  }
-}
-</style>

+ 0 - 15
src/views/customer/reportStatistic/Index.vue

@@ -1,15 +0,0 @@
-<script setup>
-import List from './List.vue'
-import Chart from './Chart.vue'
-
-const activeComp=shallowRef(List)
-
-function changeComp(type){
-  activeComp.value=type==='list'?Chart:List
-}
-
-</script>
-
-<template>
-  <component :is="activeComp" @change="changeComp"></component>
-</template>

+ 0 - 248
src/views/customer/reportStatistic/List.vue

@@ -1,248 +0,0 @@
-<script setup>
-import { Search,Switch } from '@element-plus/icons-vue'
-import { apiCustomerStatistic } from '@/api/customer'
-import UserStatisticDetail from './components/UserStatisticDetail.vue'
-import { useRouter } from 'vue-router'
-
-const router=useRouter()
-
-const emits=defineEmits(['change'])
-
-const filterState=reactive({
-  keyword: '',
-  seller: '',
-  status: '',
-  register: '',
-  subscribe: '',
-  regsiterTime: [],
-  createTime: []
-})
-
-const tableColOpt = [
-  {
-    label: '姓名',
-    key: 'RealName'
-  },
-  {
-    label: '手机号',
-    key: 'Phone'
-  },
-  {
-    label: '邮箱',
-    key: 'Email'
-  },
-  {
-    label: '营业部/销售',
-    key: 'SellerName'
-  },
-  {
-    label: '用户状态',
-    key: 'Status'
-  },
-  {
-    label: '最近一次阅读时间',
-    key: 'LastUpdateTime',
-    sort: true
-  },
-  {
-    label: '累计阅读次数',
-    key: 'ReadCnt',
-    sort: true
-  }
-]
-const userList = ref([])
-const page = ref(1)
-const pageSize = ref(10)
-const tableLoading = ref(false)
-const totals = ref(0)
-async function getUserList() {
-  tableLoading.value = true
-  const res = await apiCustomerStatistic.readRecordList({
-    PageSize: pageSize.value,
-    CurrentIndex: page.value,
-    KeyWord: filterState.keyword,
-    SellerId:filterState.seller?filterState.seller.join(','):'',
-    Status: filterState.status,
-    IsRegistered: filterState.register,
-    IsSubscribed: filterState.subscribe,
-    RegisterStartDate: filterState.regsiterTime ? filterState.regsiterTime[0] : '',
-    RegisterEndDate: filterState.regsiterTime ? filterState.regsiterTime[1] : '',
-    CreateStartDate: filterState.createTime ? filterState.createTime[0] : '',
-    CreateEndDate: filterState.createTime ? filterState.createTime[1] : '',
-    SortParam:filterState.sortType,
-    SortType:filterState.sortVal
-  })
-  tableLoading.value = false
-  if (res.Ret === 200) {
-    userList.value = res.Data.List || []
-    totals.value = res.Data.Paging.Totals
-  }
-}
-getUserList()
-function handlePageChange(e) {
-  page.value = e
-  getUserList()
-}
-function handleTableSort(e) {
-  // console.log(e);
-  const { order, prop } = e//order:"descending",prop: "RegisterTime"
-  filterState.sortType=prop
-  if(!order){
-    filterState.sortVal=''
-  }else{
-    filterState.sortVal=order==='descending'?'desc':'asc'
-  }
-  handleFilterList()
-}
-function handleFilterList() {
-  page.value = 1
-  getUserList()
-}
-
-
-const showDetail=ref(false)
-const activeUserId=ref(0)
-const activeUserName=ref('')
-function handleShowDetail(e){
-  activeUserId.value=e.UserId
-  activeUserName.value=e.RealName
-  showDetail.value=true
-}
-
-// 跳转详情
-function handleGoDetail(e){
-  const link=router.resolve({
-    path:'/customer/userDetail',
-    query:{
-      id:e.UserId
-    }
-  }).href
-  window.open(link,'__blank')
-}
-
-</script>
-
-<template>
-  <div class="user-report-statistic-page">
-    <div class="flex filter-wrap">
-      <el-button type="primary" :icon="Switch" link @click="emits('change','list')">统计图</el-button>
-      <all-user-for-depart
-        style="width: 165px"
-        v-model="filterState.seller"
-        :props="{
-          emitPath: false,
-          multiple: true,
-        }"
-        clearable
-        filterable
-        @change="handleFilterList"
-      />
-      <el-select
-        placeholder="用户状态"
-        v-model="filterState.status"
-        style="width: 165px"
-        @change="handleFilterList"
-      >
-        <el-option label="启用" :value="1"></el-option>
-        <el-option label="禁用" :value="0"></el-option>
-      </el-select>
-      <el-select
-        placeholder="注册状态"
-        v-model="filterState.register"
-        style="width: 165px"
-        @change="handleFilterList"
-      >
-        <el-option label="是" value="是"></el-option>
-        <el-option label="否" value="否"></el-option>
-      </el-select>
-      <el-select
-        placeholder="是否关注公众号"
-        v-model="filterState.register"
-        style="width: 165px"
-        @change="handleFilterList"
-      >
-        <el-option label="是" value="是"></el-option>
-        <el-option label="否" value="否"></el-option>
-      </el-select>
-      <span style="width: 235px">
-        <el-date-picker
-          style="width: 235px"
-          v-model="filterState.regsiterTime"
-          type="daterange"
-          range-separator="至"
-          start-placeholder="注册时间"
-          end-placeholder="注册时间"
-          value-format="YYYY-MM-DD"
-          @change="handleFilterList"
-        />
-      </span>
-      <span style="width: 235px">
-        <el-date-picker
-          style="width: 235px"
-          v-model="filterState.createTime"
-          type="daterange"
-          range-separator="至"
-          start-placeholder="创建时间"
-          end-placeholder="创建时间"
-          value-format="YYYY-MM-DD"
-          @change="handleFilterList"
-        />
-      </span>
-      <el-input
-        placeholder="姓名/手机号/邮箱"
-        v-model="filterState.keyword"
-        :prefix-icon="Search"
-        clearable
-        style="max-width: 359px;margin-left:auto"
-        @input="handleFilterList"
-      />
-    </div>
-    <div class="userlist-wrap" style="margin-top: 20px">
-      <el-table
-        :data="userList"
-        border
-        stripe
-        highlight-current-row
-        element-loading-text="数据加载中..."
-        v-loading="tableLoading"
-        @sort-change="handleTableSort"
-        @row-click="handleGoDetail"
-      >
-        <el-table-column
-          v-for="column in tableColOpt"
-          :key="column.key"
-          :prop="column.key"
-          :label="column.label"
-          :sortable="column.sort ? 'custom' : false"
-        >
-          <template #default="{ row }">
-            <span
-              v-if="column.key === 'Status'"
-              :style="{ color: !row.Status ? '#f00' : '' }"
-              >{{ row.Status ? "启用" : "禁用" }}</span
-            >
-            <el-button v-else-if="column.key === 'ReadCnt'&&row.ReadCnt>0" link type="primary" @click.stop="handleShowDetail(row)">{{row.ReadCnt}}</el-button>
-            <span v-else>{{ row[column.key] }}</span>
-          </template>
-        </el-table-column>
-      </el-table>
-      <el-pagination
-        background
-        layout="total,prev,pager,next"
-        :current-page="page"
-        :page-size="pageSize"
-        :total="totals"
-        @current-change="handlePageChange"
-        style="margin-top: 30px;justify-content: flex-end;"
-      />
-    </div>
-  </div>
-  <UserStatisticDetail v-model:show="showDetail" :userId="activeUserId" :userName="activeUserName"/>
-</template>
-
-<style lang="scss" scoped>
-.filter-wrap{
-  gap: 10px;
-  flex-wrap: wrap;
-}
-</style>

+ 0 - 103
src/views/customer/reportStatistic/components/LineChart.vue

@@ -1,103 +0,0 @@
-<script setup>
-import { dayjs } from "element-plus"
-import { apiCustomerStatistic } from '@/api/customer'
-import { lineChartRender } from '../utils/chartRender'
-
-const props = defineProps({
-  userId: ''
-})
-
-const permission = ref('')
-const classify = ref('')
-const time = ref([dayjs().subtract(1, 'year').format('YYYY-MM-DD'), dayjs().format('YYYY-MM-DD')])
-
-
-function getChartData() {
-  apiCustomerStatistic.readTimesChartData({
-    UserId: props.userId || 0,
-    ChartPermissionIds: permission.value ? permission.value.join(',') : '',
-    ClassifyIds: classify.value ? classify.value.join(',') : '',
-    StartDate: time.value ? time.value[0] : '',
-    EndDate: time.value ? time.value[1] : '',
-  }).then(res => {
-    if (res.Ret === 200) {
-      const arr = res.Data || []
-      let data = {
-        time: [],
-        value: []
-      }
-      arr.forEach(item => {
-        data.time.push(item.CreateDate)
-        data.value.push(item.Count)
-      })
-      lineChartRender(data)
-    }
-  })
-}
-getChartData()
-
-watch(
-  () => props.userId,
-  (n) => {
-    getChartData()
-  }
-)
-
-
-
-</script>
-
-<template>
-  <div class="read-times-wrap">
-    <div class="flex filter-wrap">
-      <select-permission
-        v-model="permission"
-        :props="{
-          emitPath: false,
-          multiple: true,
-        }"
-        clearable
-        @change="getChartData"
-      />
-      <select-report-classify
-        v-model="classify"
-        :props="{
-          emitPath: false,
-          multiple: true,
-        }"
-        clearable
-        @change="getChartData"
-      />
-      <span style="width: 235px">
-        <el-date-picker
-          style="width: 235px"
-          v-model="time"
-          type="daterange"
-          range-separator="至"
-          start-placeholder="开始时间"
-          end-placeholder="结束时间"
-          value-format="YYYY-MM-DD"
-          @change="getChartData"
-        />
-      </span>
-    </div>
-    <h3 style="text-align: center">用户阅读量统计图</h3>
-    <div class="chart-box" id="chartBox1"></div>
-  </div>
-</template>
-
-<style lang="scss" scoped>
-.filter-wrap {
-  gap: 10px;
-}
-.read-times-wrap {
-  height: calc(100vh - 200px);
-  padding-top: 30px;
-  padding-left: 30px;
-  padding-right: 30px;
-  .chart-box {
-    margin-top: 80px;
-    height: 400px;
-  }
-}
-</style>

+ 0 - 55
src/views/customer/reportStatistic/components/PieChart.vue

@@ -1,55 +0,0 @@
-<script setup>
-import { apiCustomerStatistic } from '@/api/customer'
-import { pieChartRender } from '../utils/chartRender'
-
-const props = defineProps({
-  userId: ''
-})
-
-function getChartData() {
-  apiCustomerStatistic.readPermissionChartData({
-    UserId: props.userId || 0,
-  }).then(res => {
-    if (res.Ret === 200) {
-      const arr = res.Data || []
-      let data = arr.map(item => {
-        return {
-          ...item,
-          name: item.PermissionName,
-          y: item.Count,
-        }
-      })
-      pieChartRender(data)
-    }
-  })
-}
-getChartData()
-
-watch(
-  () => props.userId,
-  (n) => {
-    getChartData()
-  }
-)
-
-</script>
-
-<template>
-  <div class="read-permission-wrap">
-    <h3 style="text-align: center">用户阅读品种分布图</h3>
-    <div class="chart-box" id="chartBox2"></div>
-  </div>
-</template>
-
-<style lang="scss" scoped>
-.read-permission-wrap {
-  height: calc(100vh - 200px);
-  padding-top: 30px;
-  padding-left: 30px;
-  padding-right: 30px;
-  .chart-box {
-    margin-top: 80px;
-    height: 400px;
-  }
-}
-</style>

+ 0 - 165
src/views/customer/reportStatistic/components/UserStatisticDetail.vue

@@ -1,165 +0,0 @@
-<script setup>
-import { apiCustomerStatistic } from '@/api/customer'
-import { watch } from 'vue'
-
-const show = defineModel('show', { type: Boolean, default: false })
-
-const props = defineProps({
-  userId: {
-    type: Number,
-    default: 0
-  },
-  userName:{
-    type:String,
-    default:''
-  }
-
-})
-
-const tableColOpt = [
-  {
-    label: '标题',
-    key: 'ReportTitle'
-  },
-  {
-    label: '品种',
-    key: 'ChartPermissionName'
-  },
-  {
-    label: '报告类型',
-    key: 'ClassifyName1'
-  },
-  {
-    label: '阅读时间',
-    key: 'CreateTime'
-  },
-  {
-    label: '停留时间',
-    key: 'StayTime'
-  },
-]
-const list = ref([])
-const page = ref(1)
-const pageSize = ref(10)
-const tableLoading = ref(false)
-const totals = ref(0)
-const permissionIds = ref('')
-const classifyIds = ref('')
-async function getList() {
-  tableLoading.value = true
-  const res = await apiCustomerStatistic.readRecordInfo({
-    UserId: props.userId,
-    PageSize: pageSize.value,
-    CurrentIndex: page.value,
-    ChartPermissionIds: permissionIds.value ? permissionIds.value.join(',') : '',
-    ClassifyIds: classifyIds.value ? classifyIds.value.join(',') : '',
-  })
-  tableLoading.value = false
-  if (res.Ret === 200) {
-    list.value = res.Data.List || []
-    totals.value = res.Data.Paging.Totals
-  }
-}
-function handlePageChange(e) {
-  page.value = e
-  getList()
-}
-
-function handleRefreshList() {
-  page.value = 1
-  list.value = []
-  getList()
-}
-
-watch(() => show.value, (n) => {
-  if (n) {
-    permissionIds.value = ''
-    classifyIds.value=''
-    handleRefreshList()
-  }
-})
-
-function formatClassifyName(e){
-  if(e.ClassifyName3){
-    return `${e.ClassifyName1}/${e.ClassifyName2}/${e.ClassifyName3}`
-  }else if(e.ClassifyName2){
-    return `${e.ClassifyName1}/${e.ClassifyName2}`
-  }else{
-    return e.ClassifyName1
-  }
-}
-
-</script>
-
-<template>
-  <el-dialog v-model="show" width="850" :title="props.userName+'研报统计'" draggable>
-    <div class="user-statistic-detail-wrap">
-      <div>
-        <select-permission
-          v-model="permissionIds"
-          :props="{
-            emitPath: false,
-            multiple: true,
-          }"
-          clearable
-          @change="handleRefreshList"
-        />
-        <select-report-classify
-          style="margin-left: 5px"
-          v-model="classifyIds"
-          :props="{
-            emitPath: false,
-            multiple: true,
-          }"
-          clearable
-          @change="handleRefreshList"
-        />
-      </div>
-      <div class="total-text">共有{{ totals }}条阅读记录</div>
-      <el-table
-        :data="list"
-        border
-        highlight-current-row
-        element-loading-text="数据加载中..."
-        v-loading="tableLoading"
-        height="500px"
-      >
-        <el-table-column
-          v-for="column in tableColOpt"
-          :key="column.key"
-          :prop="column.key"
-          :label="column.label"
-        >
-          <template #default="{ row }">
-            <span v-if="column.key === 'CreateTime'">{{
-              formatTime(row.CreateTime)
-            }}</span>
-            <span v-else-if="column.key === 'ClassifyName1'">{{
-              formatClassifyName(row)
-            }}</span>
-            <span v-else>{{ row[column.key] }}</span>
-          </template>
-        </el-table-column>
-      </el-table>
-      <el-pagination
-        background
-        layout="total,prev,pager,next"
-        :current-page="page"
-        :page-size="pageSize"
-        :total="totals"
-        @current-change="handlePageChange"
-        style="margin-top: 30px; justify-content: flex-end"
-      />
-    </div>
-  </el-dialog>
-</template>
-
-<style lang="scss" scoped>
-.user-statistic-detail-wrap {
-  .total-text {
-    color: #000;
-    margin-top: 30px;
-    margin-bottom: 10px;
-  }
-}
-</style>

+ 0 - 140
src/views/customer/reportStatistic/utils/chartRender.js

@@ -1,140 +0,0 @@
-import Highcharts from "highcharts/highstock";
-
-const chartBaseConfig = {
-  title: {
-    text: "",
-  },
-  accessibility: {
-    enabled: false,
-  },
-  chart: {
-    style: {
-      fontSize: 16,
-    },
-  },
-  credits: {
-    enabled: false,
-  },
-  legend: {
-    align: "center",
-    verticalAlign: "top",
-  },
-};
-
-export function lineChartRender(data) {
-  let options = {
-    // colors: ["#436DFF", "#25DEDB"],
-    plotOptions: {
-      series: {
-        marker: {
-          fillColor: "#FFFFFF",
-          lineWidth: 2,
-          lineColor: null,
-        },
-      },
-    },
-    xAxis: {
-      categories: data.time,
-      labels: {
-        style: {
-          color: "#999",
-        },
-      },
-      tickWidth: 1,
-      tickLength: 5,
-      lineColor:'#bfbfbf',
-      tickColor:'#bfbfbf',
-    },
-    yAxis: [
-      {
-        gridLineWidth: 0,
-        lineWidth: 1,
-        lineColor:'#bfbfbf',
-        tickColor:'#bfbfbf',
-        tickWidth: 1,
-        tickLength: 5,
-        labels: {
-          style: {
-            color: "#999",
-          },
-        },
-        title: {
-          text: "次",
-          align: "high",
-          style: {
-            color: "#999",
-          },
-          y: -10,
-          offset: 0,
-          rotation: 0,
-        },
-      },
-    ],
-    tooltip: {
-      format: '<span style="font-size: 0.8em">{key}</span><br/>'+
-      '<span style="color:{color}">\u25CF</span> ' +
-      '{series.name}: <b>{y}</b><br/>',
-    },
-    series: [
-      {
-        data: data.value,
-        type: "line",
-        name: "阅读量",
-        yAxis: 0,
-      },
-    ],
-    ...chartBaseConfig,
-  };
-  Highcharts.chart("chartBox1", options);
-}
-
-export function pieChartRender(data) {
-  let options = {
-    ...chartBaseConfig,
-    // colors: ["#59F7CA", "#62F2F8", "#F2B949", "#FF8838", "#FDFDFD", "#4A7CE9"],
-    credits: {
-      enabled: false,
-    },
-    chart: {
-      ...chartBaseConfig.chart,
-    },
-    title: {
-      text: "",
-    },
-    legend: {
-      ...chartBaseConfig.legend,
-      align: "right",
-      verticalAlign: "top",
-      layout: "vertical",
-      x: 0,
-      y: 0,
-    },
-    tooltip: {
-      shared: false,
-      pointFormat: '<span>{point.y}次:{point.Percent}%<br/>'
-    },
-    plotOptions: {
-      pie: {
-        allowPointSelect: true,
-        cursor: "pointer",
-        dataLabels: {
-          enabled: true,
-          distance: -10,
-          format: "",
-        },
-        showInLegend: true,
-      },
-    },
-    series: [
-      {
-        type: "pie",
-        innerSize: "80%",
-        name: "",
-        colorByPoint: true,
-        borderRadius: 0,
-        data: data,
-      },
-    ],
-  };
-  Highcharts.chart("chartBox2", options);
-}

+ 13 - 0
src/views/media/AudioList.vue

@@ -0,0 +1,13 @@
+<script setup>
+import { ref, reactive } from 'vue'
+</script>
+
+<template>
+    <div>
+        音频管理
+    </div>
+</template>
+
+<style scoped lang="scss">
+
+</style>

+ 13 - 0
src/views/media/PictureLibrary.vue

@@ -0,0 +1,13 @@
+<script setup>
+import { ref, reactive } from 'vue'
+</script>
+
+<template>
+    <div>
+        图片资源库
+    </div>
+</template>
+
+<style scoped lang="scss">
+
+</style>

+ 13 - 0
src/views/media/VideoList.vue

@@ -0,0 +1,13 @@
+<script setup>
+import { ref, reactive } from 'vue'
+</script>
+
+<template>
+    <div>
+        视频管理
+    </div>
+</template>
+
+<style scoped lang="scss">
+
+</style>

+ 0 - 360
src/views/report/pdf/List.vue

@@ -1,360 +0,0 @@
-<script setup>
-import { Search, Plus } from '@element-plus/icons-vue'
-import EditPdf from './components/EditPdf.vue'
-import { apiReportPdf } from '@/api/report'
-import { dayjs, ElMessage, ElMessageBox } from 'element-plus'
-
-const filterState = reactive({
-  keyword: '',
-  classifyIds: '',
-  status: '',
-  publishTime: [],
-  updateTime: [],
-  sortType:'',
-  sortVal:''
-})
-
-const tableColOpt = [
-  {
-    label: '报告标题',
-    key: 'Title'
-  },
-  {
-    label: '类型',
-    key: 'ClassifyNameFirst'
-  },
-  {
-    label: '作者',
-    key: 'Author'
-  },
-  {
-    label: '摘要',
-    key: 'Abstract'
-  },
-  {
-    label: '状态',
-    key: 'State',
-    width: '100px'
-  },
-  {
-    label: '创建人',
-    key: 'SysRealName'
-  },
-  {
-    label: '发布时间',
-    key: 'PublishTime',
-    sort: true,
-    width: '200px'
-  },
-  {
-    label: '更新时间',
-    key: 'ModifyTime',
-    sort: true,
-    width: '200px'
-  },
-  {
-    label: '期数',
-    key: 'Stage',
-    width: '100px'
-  },
-  {
-    label: 'PV/UV',
-    key: 'Pv',
-    headerTips: 'pv:报告被打开的次数,每次打开都计算一次<br> uv:访问报告的人数,每篇报告同一个人访问只计算一次'
-  }
-]
-function getTitleTime(e) {
-  if (e.PublishTime) {
-    return dayjs(e.PublishTime).format('MMDD')
-  }
-  return dayjs(e.ModifyTime).format('MMDD')
-}
-
-const pdfList = ref([])
-const page = ref(1)
-const pageSize = ref(10)
-const tableLoading = ref(false)
-const totals = ref(0)
-async function getReportList() {
-  tableLoading.value = true
-  const res = await apiReportPdf.reportPdfList({
-    PageSize: pageSize.value,
-    CurrentIndex: page.value,
-    ClassifyIds:filterState.classifyIds ? filterState.classifyIds.join(',') : '',
-    State:filterState.status,
-    PublishStartDate:filterState.publishTime ? filterState.publishTime[0] : '',
-    PublishEndDate:filterState.publishTime ? filterState.publishTime[1] : '',
-    ModifyStartDate:filterState.updateTime ? filterState.updateTime[0] : '',
-    ModifyEndDate:filterState.updateTime ? filterState.updateTime[1] : '',
-    KeyWord:filterState.keyword,
-    SortParam:filterState.sortType,
-    SortType:filterState.sortVal
-  })
-  tableLoading.value = false
-  if (res.Ret === 200) {
-    pdfList.value = res.Data.List || []
-    totals.value = res.Data.Paging.Totals
-  }
-}
-getReportList()
-function handlePageChange(e) {
-  page.value = e
-  getReportList()
-}
-function handleTableSort(e) {
-  // console.log(e);
-  const { order, prop } = e//order:"descending",prop: "RegisterTime"
-  filterState.sortType = prop
-  if (!order) {
-    filterState.sortVal = ''
-  } else {
-    filterState.sortVal = order === 'descending' ? 'desc' : 'asc'
-  }
-
-  handleFilterList()
-}
-function handleFilterList() {
-  page.value = 1
-  getReportList()
-}
-
-
-const showEdit = ref(false)
-const editData = ref(null)
-function handleEditPdf(e){
-  editData.value=e
-  showEdit.value=true
-}
-
-async function handleReportCancelPublish(e){
-  await ElMessageBox.confirm('是否确认撤销改报告','提示')
-  const res=await apiReportPdf.reportPdfCancelPubllish({
-    ReportPdfId:e.ReportPdfId
-  })
-  if(res.Ret===200){
-    ElMessage.success('撤销成功')
-    handleFilterList()
-  }
-}
-
-async function handleReportPublish(e){
-  const res=await apiReportPdf.reportPdfPubllish({
-    ReportPdfId:e.ReportPdfId
-  })
-  if(res.Ret===200){
-    ElMessage.success('发布成功')
-    handleFilterList()
-  }
-}
-
-async function handleReportDelete(e){
-  await ElMessageBox.confirm('报告删除后无法恢复,确认删除吗?','提示')
-  const res=await apiReportPdf.reportPdfDelete({
-    ReportPdfId:e.ReportPdfId
-  })
-  if(res.Ret===200){
-    ElMessage.success('删除成功')
-    handleFilterList()
-  }
-}
-
-function handlePreviewPdf(e){
-  window.open(e.PdfUrl,'__blank')
-}
-
-function getClassifyName(e){
-  if(e.ClassifyNameThird){
-    return `${e.ClassifyNameFirst}/${e.ClassifyNameSecond}/${e.ClassifyNameThird}`
-  }else if(e.ClassifyNameSecond){
-    return `${e.ClassifyNameFirst}/${e.ClassifyNameSecond}`
-  }else{
-    return e.ClassifyNameFirst
-  }
-}
-
-</script>
-
-<template>
-  <div class="report-pdf-list-page">
-    <div>
-      <el-button v-permission="'reportPdf:add'" type="primary" :icon="Plus" @click="showEdit = true;editData=null"
-        >上传报告</el-button
-      >
-      <el-input
-        placeholder="报告标题/创建人"
-        v-model="filterState.keyword"
-        :prefix-icon="Search"
-        clearable
-        style="max-width: 359px; float: right"
-        @input="handleFilterList"
-      />
-    </div>
-    <div class="flex filter-wrap">
-      <select-report-classify
-        v-model="filterState.classifyIds"
-        clearable
-        :props="{
-          emitPath: false,
-          multiple: true,
-        }"
-        @change="handleFilterList"
-      />
-      <el-select
-        placeholder="状态"
-        v-model="filterState.status"
-        style="width: 165px"
-        clearable
-        @change="handleFilterList"
-      >
-        <el-option label="已发布" :value="1"></el-option>
-        <el-option label="未发布" :value="2"></el-option>
-      </el-select>
-
-      <div style="width: 235px">
-        <el-date-picker
-          style="width: 235px"
-          v-model="filterState.publishTime"
-          type="daterange"
-          range-separator="至"
-          start-placeholder="发布时间"
-          end-placeholder="发布时间"
-          clearable
-          value-format="YYYY-MM-DD"
-          @change="handleFilterList"
-        />
-      </div>
-      <div style="width: 235px">
-        <el-date-picker
-          style="width: 235px"
-          v-model="filterState.updateTime"
-          type="daterange"
-          range-separator="至"
-          start-placeholder="更新时间"
-          end-placeholder="更新时间"
-          value-format="YYYY-MM-DD"
-          clearable
-          @change="handleFilterList"
-        />
-      </div>
-    </div>
-    <div class="list-wrap" style="margin-top: 20px">
-      <el-table
-        :data="pdfList"
-        border
-        stripe
-        highlight-current-row
-        element-loading-text="数据加载中..."
-        v-loading="tableLoading"
-        @sort-change="handleTableSort"
-      >
-        <el-table-column
-          v-for="column in tableColOpt"
-          :key="column.key"
-          :prop="column.key"
-          :label="column.label"
-          :sortable="column.sort ? 'custom' : false"
-          :width="column.width"
-        >
-          <template v-if="column.headerTips" #header>
-            <span>{{ column.label }}</span>
-            <el-tooltip
-              class="box-item"
-              effect="dark"
-              raw-content
-              :content="column.headerTips"
-              placement="top"
-            >
-              <el-icon style="position: relative; top: 2px"
-                ><i-ep-QuestionFilled
-              /></el-icon>
-            </el-tooltip>
-          </template>
-          <template #default="{ row }">
-            <span v-if="column.key === 'Title'"
-              @click="handlePreviewPdf(row)"
-              >{{ row.Title }}({{ getTitleTime(row) }})</span
-            >
-            <span v-else-if="column.key === 'ClassifyNameFirst'">{{getClassifyName(row)}}</span>
-            <span v-else-if="column.key === 'State'">{{
-              row.State === 1 ? "已发布" : "未发布"
-            }}</span>
-            <span v-else-if="column.key === 'PublishTime'">{{
-              formatTime(row.PublishTime)
-            }}</span>
-            <span v-else-if="column.key === 'ModifyTime'">{{
-              formatTime(row.ModifyTime)
-            }}</span>
-            <span v-else-if="column.key === 'Stage'">第{{ row.Stage }}期</span>
-            <span v-else-if="column.key === 'Pv'"
-              >{{ row.Pv }} / {{ row.Uv }}</span
-            >
-            <span v-else>{{ row[column.key] }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="操作" width="160">
-          <template #default="{ row }">
-            <el-button
-              v-permission="'reportPdf:edit'"
-              type="primary"
-              link
-              @click="handleEditPdf(row)"
-              >编辑</el-button
-            >
-            <el-button
-              v-permission="'reportPdf:publishCancel'"
-              type="primary"
-              link
-              v-if="row.State===1"
-              @click="handleReportCancelPublish(row)"
-              >撤销</el-button
-            >
-            <el-button
-              v-permission="'reportPdf:publish'"
-              type="primary"
-              link
-              v-if="row.State===2"
-              @click="handleReportPublish(row)"
-              >发布</el-button
-            >
-            <el-button
-              v-permission="'reportPdf:delete'"
-              type="danger"
-              link
-              v-if="row.State===2"
-              @click="handleReportDelete(row)"
-              >删除</el-button
-            >
-            
-          </template>
-        </el-table-column>
-      </el-table>
-      <el-pagination
-        background
-        layout="total,prev,pager,next,jumper"
-        :current-page="page"
-        :page-size="pageSize"
-        :total="totals"
-        @current-change="handlePageChange"
-        style="margin-top: 30px; justify-content: flex-end"
-      />
-    </div>
-  </div>
-
-  <EditPdf 
-    v-model:show="showEdit" 
-    :defaultData="editData"
-    @success="handleFilterList"
-  />
-</template>
-
-<style lang="scss" scoped>
-.report-pdf-list-page {
-  width: 100%;
-  overflow: hidden;
-  .filter-wrap {
-    margin-top: 10px;
-    flex-wrap: wrap;
-    gap: 10px;
-  }
-}
-</style>

+ 0 - 176
src/views/report/pdf/components/EditPdf.vue

@@ -1,176 +0,0 @@
-<script setup>
-import { Plus, CircleClose } from '@element-plus/icons-vue'
-import SelectAuthor from './SelectAuthor.vue'
-import {apiReportPdf} from '@/api/report'
-import { ElMessage } from 'element-plus'
-
-const show = defineModel('show', { type: Boolean, default: false })
-const emits=defineEmits(['success'])
-
-const props=defineProps({
-  defaultData:{
-    type:[Object,null],
-    default:null
-  }
-})
-
-const formIns = ref(null)
-const FORM_RULES = {
-  title: [{ required: true, message: '请填写报告标题' }],
-  classify:[{ required: true, message: '请选择报告分类' }]
-}
-const formData = reactive({
-  fileUrl: '',
-  fileName: '',
-  title: "",
-  classify: '',
-  abstract: '',
-  author: ''
-})
-
-watch(()=>show.value,(n)=>{
-  if(n&&props.defaultData){
-    formData.fileUrl=props.defaultData.PdfUrl
-    formData.fileName=props.defaultData.PdfName
-    formData.title=props.defaultData.Title
-    if(props.defaultData.ClassifyIdThird){
-      formData.classify=[props.defaultData.ClassifyIdFirst,props.defaultData.ClassifyIdSecond,props.defaultData.ClassifyIdThird]
-    }else if(props.defaultData.ClassifyIdSecond){
-      formData.classify=[props.defaultData.ClassifyIdFirst,props.defaultData.ClassifyIdSecond]
-    }else{
-      formData.classify=[props.defaultData.ClassifyIdFirst]
-    }
-    
-    formData.abstract=props.defaultData.Abstract
-    formData.author=props.defaultData.Author?props.defaultData.Author.split(','):''
-  }else{
-    for(let key in formData){
-      formData[key]=''
-    }
-  }
-})
-
-function handleUploadSuccess(e) {
-  formData.fileUrl = e.Url
-  formData.fileName = e.FileName
-  if(!formData.title){
-    formData.title=e.FileName
-  }
-  
-}
-
-async function onSubmit() {
-  await formIns.value.validate()
-  if(!formData.fileUrl) {
-    ElMessage.warning('请上传报告PDF文件')
-    return
-  }
-  const params={
-    PdfUrl:formData.fileUrl,
-    PdfName:formData.fileName,
-    Title:formData.title,
-    Author:formData.author?formData.author.join(','):'',
-    Abstract:formData.abstract,
-    ClassifyIdFirst:formData.classify?formData.classify[0]:0,
-    ClassifyIdSecond:formData.classify?formData.classify[1]||0:0,
-    ClassifyIdThird:formData.classify?formData.classify[2]||0:0,
-  }
-  const res=props.defaultData?await apiReportPdf.reportPdfEdit({
-    ReportPdfId:props.defaultData.ReportPdfId,
-    ...params,
-  }):await apiReportPdf.reportPdfAdd(params)
-
-  if(res.Ret===200){
-    ElMessage.success('保存成功')
-    show.value=false
-    emits('success')
-  }
-
-}
-
-</script>
-
-<template>
-  <el-dialog v-model="show" width="700" :title="props.defaultData?'编辑':'上传报告'" draggable>
-    <el-form
-      ref="formIns"
-      label-width="80px"
-      :rules="FORM_RULES"
-      :model="formData"
-      @submit="onSubmit"
-      class="form-wrap"
-    >
-      <upload-file
-        accept="application/pdf"
-        :fileSize="15"
-        @success="handleUploadSuccess"
-        class="upload-box"
-      >
-        <div v-if="formData.fileUrl" class="file-name-box">
-          <span style="font-size:18px;color:var(--el-primary-color)">{{ formData.fileName }}</span>
-          <el-icon color="#f00" size="20px" @click="formData.fileName='';formData.fileUrl=''"><CircleClose /></el-icon>
-        </div>
-        <template #trigger>
-          <el-button
-            class="upload-btn"
-            type="primary"
-            plain
-            :icon="Plus"
-            v-if="!formData.fileUrl"
-            >上传报告</el-button
-          >
-        </template>
-
-        <template #tip>
-          <div>要求文件格式为pdf,且不超过15M</div>
-        </template>
-      </upload-file>
-
-      <el-form-item label="报告标题" prop="title">
-        <el-input v-model="formData.title" placeholder="请输入报告标题" />
-      </el-form-item>
-      <el-form-item label="分类" prop="classify">
-        <select-report-classify style="width:100%" v-model="formData.classify"/>
-      </el-form-item>
-      <el-form-item label="摘要" prop="abstract">
-        <el-input
-          type="textarea"
-          v-model="formData.abstract"
-          placeholder="请输入报告摘要"
-        />
-      </el-form-item>
-      <el-form-item label="作者" prop="author">
-        <SelectAuthor multiple v-model="formData.author" />
-      </el-form-item>
-    </el-form>
-
-    <div style="text-align: center">
-      <el-button type="primary" plain size="large" @click="show = false"
-        >取消</el-button
-      >
-      <el-button type="primary" size="large" @click="onSubmit">保存</el-button>
-    </div>
-  </el-dialog>
-</template>
-
-<style lang="scss" scoped>
-.form-wrap {
-  width: 500px;
-  margin: 0 auto;
-}
-.upload-box {
-  text-align: center;
-  margin-bottom: 20px;
-  .file-name-box{
-    margin-bottom: 20px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    gap: 0 10px;
-  }
-  .upload-btn {
-    width: 500px;
-    margin-bottom: 10px;
-  }
-}
-</style>

+ 0 - 47
src/views/report/pdf/components/SelectAuthor.vue

@@ -1,47 +0,0 @@
-<script setup>
-import { apiReportCommon } from '@/api/report'
-
-const model = defineModel()
-const props = defineProps({
-  props: {},
-  clearable: {
-    type: Boolean,
-    default: false
-  },
-  multiple: {
-    type: Boolean,
-    default: false
-  },
-
-})
-const emits = defineEmits(['change'])
-
-const options = ref([])
-async function getData() {
-  const res = await apiReportCommon.reportAuthorList()
-  if (res.Ret != 200) return
-  const arr = res.Data || []
-  options.value = arr
-}
-getData()
-
-function handleChange() {
-  emits('change')
-}
-
-</script>
-<template>
-  <el-select
-    collapse-tags
-    :multiple="props.multiple"
-    v-model="model"
-    placeholder="请选择作者"
-  >
-    <el-option
-      v-for="item in options"
-      :key="item.Id"
-      :label="item.ReportAuthor"
-      :value="item.ReportAuthor"
-    />
-  </el-select>
-</template>