Ver Fonte

Merge branch 'dev/v1.0.36_tsz' of jianyu/web into feature/v1.0.36

汤世哲 há 1 ano atrás
pai
commit
15f7dce1c1

+ 2 - 1
apps/bigmember_pc/src/utils/visited/transform.js

@@ -12,7 +12,8 @@ const Rules = {
   ent: 'ent(_ser)?_portrait',
   buyer: 'client_portrayal',
   project: 'client_follow_detail',
-  demand: 'demand/detail/*'
+  demand: 'demand/detail/*',
+  proposed: 'proposed/detail/*'
 }
 
 /**

+ 3 - 0
apps/bigmember_pc/src/views/search/components/SearchHeader.vue

@@ -1,5 +1,8 @@
 <template>
   <div class="search-header">
+    <div class="search-header-tab">
+      <slot name="tab-switch"></slot>
+    </div>
     <div class="search-header-content">
       <div class="search-header-top">
         <SearchInput

+ 3 - 0
apps/bigmember_pc/src/views/search/components/search-header-card.vue

@@ -37,6 +37,9 @@ const props = defineProps({
       @input="$emit('input', $event)"
       @search="$emit('search')"
     >
+      <div class="tab-switch" slot="tab-switch">
+        <slot name="tab-switch-content"></slot>
+      </div>
       <slot></slot>
     </search-header>
   </div>

+ 10 - 2
apps/bigmember_pc/src/views/search/layout/search-list.vue

@@ -40,6 +40,10 @@ const props = defineProps({
       pageSize: 50, // 每页多少条数据
       total: 0 // 一共多少条数据
     })
+  },
+  mtb60: {
+    type: Boolean,
+    default: true
   }
 })
 console.log(props.headerActions)
@@ -109,7 +113,11 @@ const canShowPagination = computed(() => {
     <div class="search-result-container">
       <slot name="list-before"></slot>
       <slot name="loading" v-if="listState.loading">
-        <empty images="jy-loading.gif" tip="剑鱼标讯正在努力工作中···"></empty>
+        <empty
+          :mtb60="mtb60"
+          images="jy-loading.gif"
+          tip="剑鱼标讯正在努力工作中···"
+        ></empty>
       </slot>
       <slot name="list" :list="list" v-else>
         <div
@@ -138,7 +146,7 @@ const canShowPagination = computed(() => {
         </div>
       </slot>
       <slot name="empty" v-if="listState.finished && list.length === 0">
-        <empty tip="这里什么也没有" images="jy-back.png"></empty>
+        <empty :mtb60="mtb60" tip="这里什么也没有" images="jy-back.png"></empty>
       </slot>
       <div
         class="search-result-footer-container p-b-16px p-r-16px p-t-24px flex flex-(col items-end)"

+ 0 - 201
apps/bigmember_pc/src/views/search/nzj/components/list-item.vue

@@ -1,201 +0,0 @@
-<script setup>
-import { computed } from 'vue'
-import { replaceKeyword, dateFromNow } from '../model/modules/utils'
-const props = defineProps({
-  index: [String, Number],
-  title: {
-    type: String,
-    default: ''
-  },
-  tagsPosition: {
-    type: String,
-    default: 'bottom'
-  },
-  detail: {
-    type: String,
-    default: ''
-  },
-  visited: {
-    type: Boolean,
-    default: false
-  },
-  time: {
-    type: Number,
-    default: 0
-  },
-  matchKeys: {
-    type: Array,
-    default() {
-      return [
-        // 'xxx',
-        // 'yyy'
-      ]
-    }
-  },
-  tagList: {
-    type: Array,
-    default() {
-      return [
-        // {
-        //   value: '河南',
-        //   className: 'grey'
-        // }
-      ]
-    }
-  }
-})
-const calcTitle = computed(() => {
-  const hightLightedTitle = replaceKeyword(props.title, props.matchKeys, [
-    '<span class="highlight-text">',
-    '</span>'
-  ])
-  if (props.index) {
-    return `${props.index}. ${hightLightedTitle}`
-  } else {
-    return hightLightedTitle
-  }
-})
-</script>
-
-<template>
-  <div class="nzj-list-item">
-    <div
-      class="article-item-content"
-      :class="{'tags-bottom': props.tagsPosition === 'bottom' }"
-    >
-      <div class="a-i-c-top visited-hd">
-        <div class="ellipsis" v-html="calcTitle"></div>
-        <div class="tags" v-if="props.tagsPosition === 'bottom'">
-          <span
-            class="tag"
-            :class="[tag.className]"
-            :key="i"
-            v-for="(tag, i) in props.tagList"
-            >{{ tag.value }}</span
-          >
-        </div>
-      </div>
-      <div class="a-i-c-bottom">
-        <div class="tags" v-if="props.tagsPosition === 'right'">
-          <span
-            class="tag"
-            :class="[tag.className]"
-            :key="i"
-            v-for="(tag, i) in props.tagList"
-            >{{ tag.value }}</span
-          >
-        </div>
-        <div class="time-container">
-          <span class="time-text">
-            <slot name="right-time">
-              <span v-if="time">{{ dateFromNow(time) }}</span>
-            </slot>
-          </span>
-        </div>
-        <slot name="actions"></slot>
-      </div>
-    </div>
-  </div>
-</template>
-
-<style lang="scss" scoped>
-.article-item-content {
-  display: flex;
-  justify-content: space-between;
-  padding: 20px;
-  flex: 1;
-  min-height: 22px;
-  .a-i-c {
-    &-top {
-      max-width: 1080px;
-      font-size: 16px;
-      line-height: 24px;
-      color: #1d1d1d;
-      .tags {
-        margin-top: 8px;
-        justify-content: flex-start;
-      }
-    }
-    &-center {
-      margin: 12px 0;
-      font-size: 14px;
-      line-height: 22px;
-      color: #686868;
-    }
-    &-bottom {
-      display: flex;
-      align-items: center;
-      justify-content: flex-end;
-    }
-  }
-
-  &.line {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    .a-i-c {
-      &-top {
-        max-width: 700px;
-      }
-      &-bottom {
-        width: unset;
-      }
-    }
-  }
-  &.tags-bottom {
-    height: auto;
-    align-items: flex-start;
-  }
-
-  .tag {
-    display: flex;
-    align-items: center;
-    padding: 1px 6px;
-    margin-right: 14px;
-    font-size: 13px;
-    line-height: 20px;
-    white-space: nowrap;
-    border: 1px solid transparent;
-    border-radius: 3px;
-
-    &.grey {
-      color: #686868;
-      border-color: #ececec;
-      background-color: #F5F5FB;
-    }
-    &.blue {
-      color: #fff;
-      background-color: #2CB7CA;
-      border-color: #2CB7CA;
-    }
-    &.orange {
-      color: #fff;
-      background-color: #ff9f40;
-      border-color: #ff9f40;
-    }
-    &.green {
-      color: #fff;
-      background-color: #00d086;
-      border-color: #00d086;
-    }
-    &.deeppink {
-      color: #fff;
-      background-color: #FF878D;
-      border-color: #FF878D;
-    }
-  }
-
-  .tags,
-  .time-container {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-  }
-
-  .tag {
-    &:not(:last-of-type) {
-      margin-right: 8px;
-    }
-  }
-}
-</style>

+ 238 - 0
apps/bigmember_pc/src/views/search/nzj/components/nzj-article-item.vue

@@ -0,0 +1,238 @@
+<script setup>
+import { computed } from 'vue'
+import { replaceKeyword, dateFromNow } from '@/utils'
+const props = defineProps({
+  index: [String, Number],
+  title: {
+    type: String,
+    default: ''
+  },
+  tagsPosition: {
+    type: String,
+    default: 'bottom'
+  },
+  detail: {
+    type: String,
+    default: ''
+  },
+  visited: {
+    type: Boolean,
+    default: false
+  },
+  time: {
+    type: Number,
+    default: 0
+  },
+  matchKeys: {
+    type: Array,
+    default() {
+      return [
+        // 'xxx',
+        // 'yyy'
+      ]
+    }
+  },
+  tagList: {
+    type: Array,
+    default() {
+      return [
+        // {
+        //   value: '河南',
+        //   className: 'grey'
+        // }
+      ]
+    }
+  }
+})
+const calcTitle = computed(() => {
+  const hightLightedTitle = replaceKeyword(props.title, props.matchKeys, [
+    '<span class="highlight-text">',
+    '</span>'
+  ])
+  if (props.index) {
+    return `${props.index}. ${hightLightedTitle}`
+  } else {
+    return hightLightedTitle
+  }
+})
+const emit = defineEmits(['onClick'])
+function onClick() {
+  emit('onClick')
+}
+</script>
+
+<template>
+  <div class="nzj-list-item">
+    <div
+      class="article-item-content"
+      :class="{
+        'tags-bottom': props.tagsPosition === 'bottom'
+      }"
+      @click="onClick"
+    >
+      <slot name="visited"></slot>
+      <div class="a-i-c-top visited-hd">
+        <div class="ellipsis" v-html="calcTitle"></div>
+        <div class="tags" v-if="props.tagsPosition === 'bottom'">
+          <span
+            class="tag"
+            :class="[tag.className]"
+            :key="i"
+            v-for="(tag, i) in props.tagList"
+            >{{ tag.value }}</span
+          >
+        </div>
+      </div>
+      <div class="a-i-c-bottom">
+        <div class="tags" v-if="props.tagsPosition === 'right'">
+          <span
+            class="tag"
+            :class="[tag.className]"
+            :key="i"
+            v-for="(tag, i) in props.tagList"
+            >{{ tag.value }}</span
+          >
+        </div>
+        <div class="time-container">
+          <span class="time-text">
+            <slot name="right-time">
+              <span v-if="time">{{ dateFromNow(time) }}</span>
+            </slot>
+          </span>
+        </div>
+        <slot name="actions"></slot>
+      </div>
+    </div>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.nzj-list-item{
+  &:hover{
+    background-color: #f5f6f7;
+  }
+  .visited {
+    .visited-hd,
+    td {
+      color: #999 !important;
+    }
+    .hover:hover {
+      color: #2CB7CA !important;
+    }
+    .visited-ft {
+      color: #9b9ca3 !important;
+    }
+  }
+  .article-item-content {
+    display: flex;
+    justify-content: space-between;
+    padding: 20px;
+    flex: 1;
+    min-height: 22px;
+    cursor: pointer;
+    .a-i-c {
+      &-top {
+        max-width: 1080px;
+        font-size: 16px;
+        line-height: 24px;
+        color: #1d1d1d;
+        .tags {
+          margin-top: 8px;
+          justify-content: flex-start;
+        }
+      }
+      &-center {
+        margin: 12px 0;
+        font-size: 14px;
+        line-height: 22px;
+        color: #686868;
+      }
+      &-bottom {
+        display: flex;
+        align-items: center;
+        justify-content: flex-end;
+      }
+    }
+
+    &.line {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      .a-i-c {
+        &-top {
+          max-width: 700px;
+        }
+        &-bottom {
+          width: unset;
+        }
+      }
+    }
+    &.tags-bottom {
+      height: auto;
+      align-items: flex-start;
+    }
+
+    .tag {
+      display: flex;
+      align-items: center;
+      padding: 1px 6px;
+      margin-right: 14px;
+      font-size: 13px;
+      line-height: 20px;
+      white-space: nowrap;
+      border: 1px solid transparent;
+      border-radius: 3px;
+
+      &.grey {
+        color: #686868;
+        border-color: #ececec;
+        background-color: #F5F5FB;
+      }
+      &.blue {
+        color: #fff;
+        background-color: #2CB7CA;
+        border-color: #2CB7CA;
+      }
+      &.orange {
+        color: #fff;
+        background-color: #ff9f40;
+        border-color: #ff9f40;
+      }
+      &.green {
+        color: #fff;
+        background-color: #00d086;
+        border-color: #00d086;
+      }
+      &.deeppink {
+        color: #fff;
+        background-color: #FF878D;
+        border-color: #FF878D;
+      }
+    }
+
+    .tags,
+    .time-container {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+    }
+
+    .tag {
+      &:not(:last-of-type) {
+        margin-right: 8px;
+      }
+    }
+    .time-container {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      .time-text {
+        margin-left: 6px;
+        font-size: 14px;
+        color: #797a7e;
+        line-height: 24px;
+      }
+    }
+  }
+}
+</style>

+ 79 - 10
apps/bigmember_pc/src/views/search/nzj/index.vue

@@ -1,11 +1,12 @@
 <script setup>
-import { ref } from 'vue'
-import listItem from './components/list-item.vue'
+import { ref, computed } from 'vue';
+import ArticleItem from './components/nzj-article-item.vue'
 import SearchHeaderCard from '@/views/search/components/search-header-card.vue'
 import SearchSchemaFilter from '@/views/search/components/search-schema-filter.vue'
 import SearchList from '@/views/search/layout/search-list.vue'
 import {
   filterState,
+  filterParams,
   searchTabs,
   inputKeywordsState,
   doSearch,
@@ -14,18 +15,40 @@ import {
   doChangePageSize,
   doChangeInput,
   doChangeFilter,
+  setSortState
 } from './model'
+import { mixinVisited } from '@/utils/mixins/visited-setup.js'
+
+const { pathVisiting, createPathItem } = mixinVisited()
 import { useSearchNzjBaseSchema } from './constant/search-filters'
 
 const SearchNzjBaseSchema = ref([])
 const isLoading = ref(true)
 const showFilter = ref(true)
-
 useSearchNzjBaseSchema().then(res => {
   SearchNzjBaseSchema.value = res
   isLoading.value = false
 })
 
+const matchKeys = computed(() => {
+  if (inputKeywordsState.value.input) {
+    return inputKeywordsState.value.input.split(' ')
+  } else {
+    return []
+  }
+})
+
+function goToDetail(item) {
+  const { proposed_id } = item
+  console.log(item.visited, 'item.visited1')
+  item.visited = true
+  pathVisiting(createPathItem('/proposed/detail', `pid=${proposed_id}`))
+  console.log(item.visited, 'item.visited2')
+  let keys = matchKeys.value.length ? matchKeys.value.join(',') : ''
+  const routeUrl = `/swordfish/page_web_pc/proposed/detail?pid=${proposed_id}&matchKey=${keys}`
+  window.open(routeUrl)
+}
+
 </script>
 
 <template>
@@ -37,16 +60,30 @@ useSearchNzjBaseSchema().then(res => {
         placeholder="输入项目名称"
         @search="doSearch"
       >
-        <div>
-          <span>筛选</span>
-          <i class="iconfont icon-zhankai"></i>
+        <div class="tab-switch-content" slot="tab-switch-content">
+          <button
+            class="tab-switch-button"
+            :class="{ active: filterParams.searchSort === 0 }"
+            @click="setSortState(0)"
+          >
+            按项目名称搜
+          </button>
+          <button
+            class="tab-switch-button"
+            :class="{ active: filterParams.searchSort === 1 }"
+            @click="setSortState(1)"
+          >
+            按单位名称搜
+          </button>
         </div>
       </search-header-card>
 
       <div class="search-nzj-filter p-l-32px p-b-16px" v-if="!isLoading">
         <div class="filter-button no-select" @click="showFilter = !showFilter">
           <span class="filter-button-text">筛选条件</span>
-          <i class="el-icon-caret-bottom"></i>
+          <i
+            :class="showFilter ? 'el-icon-caret-bottom' : 'el-icon-caret-top'"
+          ></i>
         </div>
         <!--  标准筛选  -->
         <search-schema-filter
@@ -63,17 +100,24 @@ useSearchNzjBaseSchema().then(res => {
       v-bind="searchListProps"
       @current-change="doChangePageNum"
       @size-change="doChangePageSize"
+      :mtb60="false"
       class="search-nzj-list-container b-rd-8px m-t-16px"
     > 
       <template v-slot:item="{ item, index }">
-        <listItem
+        <ArticleItem
           :title="item.projectname"
           :item="item"
+          :class="{ visited: item.visited }"
           :time="item.lasttime"
+          :visited="item.visited"
           :tag-list="item.tagList"
+          :match-keys="matchKeys"
           tags-position="bottom"
           :index="index"
-        ></listItem>
+          v-visited:proposed="item._id"
+          @onClick="goToDetail(item)"
+        >
+        </ArticleItem>
       </template>
     </search-list>
   </div>
@@ -89,8 +133,33 @@ useSearchNzjBaseSchema().then(res => {
     }
   }
   .search-nzj-header-container {
-    background-color: #fff;
+    // background-color: #fff;
+    .search-header-card{
+      background-color: #fff;
+    }
+    .tab-switch-content {
+      height: 26px;
+      .tab-switch-button{
+        padding: 2px 14px 20px;
+        line-height: 22px;
+        border-radius: 8px;
+        font-size: 14px;
+        color: #686868;
+        background: transparent;
+        &.active {
+          color: #fff;
+          background: #2CB7CA;
+        }
+      }
+    }
     .search-nzj-filter {
+      margin-top: 16px;
+      background-color: #fff;
+      ::v-deep{
+        .flex-items-start {
+          border-bottom: 1px dashed rgba(0,0,0,.05);
+        }
+      }
       .filter-button {
         display: flex;
         align-items: center;

+ 16 - 8
apps/bigmember_pc/src/views/search/nzj/model/index.js

@@ -41,7 +41,13 @@ function doQuery(params = {}) {
 function doSearch() {
   return doQuery()
 }
-let filterParams = reactive({})
+let filterParams = reactive({
+  area: '', // 地区
+  category: '',
+  project_stage: '', // 项目阶段
+  ownerclass: '', // 业主类型
+  searchSort: 0
+})
 // 列表状态
 const listState = reactive({
   finished,
@@ -51,6 +57,10 @@ const listState = reactive({
   total
 })
 
+function setSortState(sort) {
+  filterParams.searchSort = sort
+}
+
 function perSortArticleItem(item, index) {
   const { pageNum, pageSize } = listState
   const tagList = []
@@ -93,7 +103,6 @@ function perSortArticleItem(item, index) {
     index: (pageNum - 1) * pageSize + index + 1
     // visited
   }
-  console.log(itemInfo, 'itemInfo')
   return itemInfo
 }
 
@@ -101,7 +110,6 @@ function perSortArticleItem(item, index) {
 // search-list 组件所需参数
 const searchListProps = computed(() => {
   const ajaxList = list.value.map(perSortArticleItem) || []
-  console.log(ajaxList, 'ajaxList')
   return {
     showSelect: false,
     headerActions: [],
@@ -167,15 +175,13 @@ function doChangeInput(data) {
   project_stage = project_stageJudge ? '' : project_stage.join(',')
   // 业主类别
   ownerclass = ownerclassJudge ? '' : ownerclass.join(',')
-  filterParams = {
-    keyWord: inputKeywordsState.value.input,
+  const filter = {
     area: area, // 地区
     category: category,
     project_stage: project_stage, // 项目阶段
-    ownerclass: ownerclass, // 业主类型
-    searchSort: 0
+    ownerclass: ownerclass // 业主类型
   }
-  console.log(filterParams, 'filterParams')
+  Object.assign(filterParams, filter)
   doQuery()
 }
 
@@ -209,8 +215,10 @@ export {
   searchListProps,
   // 搜索UI
   filterState,
+  filterParams,
   doChangeFilter,
   doChangeInput,
+  setSortState,
   searchTabs,
   inputKeywordsState,
   doSearch,

+ 0 - 163
apps/bigmember_pc/src/views/search/nzj/model/modules/utils.js

@@ -1,163 +0,0 @@
-function replaceKeyword (value, oldChar, newChar) {
-  if (!oldChar || !newChar) return value
-  // oldChar的字符串数组,用来循环替换
-  let oldCharArr = []
-
-  if (Array.isArray(oldChar)) {
-    oldCharArr = oldChar.concat()
-  } else {
-    oldCharArr.push(oldChar)
-  }
-
-  // 数组去重
-  oldCharArr = Array.from(new Set(oldCharArr))
-
-  try {
-    oldCharArr.forEach(function (item) {
-      // 去空格之后为空字符串,则直接跳过当前替换
-      if (item.replace(/\s+/g, '')) {
-        let oc = item
-        oc = oc.replace(/\$/g, '\\$')
-          .replace(/\(/g, '\\(')
-          .replace(/\)/g, '\\)')
-          .replace(/\*/g, '\\*')
-          .replace(/\+/g, '\\+')
-          .replace(/\./g, '\\.')
-          .replace(/\[/g, '\\[')
-          .replace(/\]/g, '\\]')
-          .replace(/\?/g, '\\?')
-          .replace(/\\/g, '\\')
-          .replace(/\//g, '\\/')
-          .replace(/\^/g, '\\^')
-          .replace(/\{/g, '\\{')
-          .replace(/\}/g, '\\}')
-          .replace(/\|/g, '\\|')
-
-        if (Array.isArray(newChar)) {
-          // 批量高亮
-          const tempV = value
-          value = value.replace(new RegExp('(' + oc + ')', 'gmi'), newChar[0] + oc + newChar[1])
-          if (value === tempV && oc.indexOf('+') !== -1) {
-            const splitReg = oc.split('\\+') || []
-            splitReg.forEach(function (v) {
-              value = value.replace(new RegExp('(' + v + ')', 'gmi'), newChar[0] + v + newChar[1])
-            })
-          }
-        } else {
-          // 普通单个高亮
-          value = value.replace(new RegExp('(' + oc + ')', 'gmi'), newChar)
-        }
-      }
-    })
-  } catch (e) {
-    console.log(e)
-    return value
-  }
-  return value
-}
-
-function dateFromNow(originTime, useOld = false) {
-  if (!originTime) return
-  // 原始时间 - 传入的时间戳
-  const originTimeStamp = +new Date(originTime)
-  // 当前时间戳
-  const nowTimeStamp = +new Date()
-  // 时间戳相差多少
-  const diffTimeStamp = nowTimeStamp - originTimeStamp
-
-  const postfix = diffTimeStamp > 0 ? '前' : '后'
-  // 求绝对值 ms(毫秒)
-  const diffTimeStampAbsMs = Math.abs(diffTimeStamp)
-  const diffTimeStampAbsS = Math.round(diffTimeStampAbsMs / 1000)
-
-  // 10天的秒数
-  const days11 = 11 * 24 * 60 * 60
-
-  const dataMap = {
-    zh: ['天', '小时', '分钟', '秒'],
-    number: [24 * 60 * 60, 60 * 60, 60, 1]
-  }
-
-  let timeString = ''
-  // 10天前
-  const tenDaysAgo = diffTimeStampAbsS > days11
-  // 是否是当天
-  const isCurrentDay =
-    dateFormatter(originTimeStamp, 'yyyy.MM.dd') ===
-    dateFormatter(nowTimeStamp, 'yyyy.MM.dd')
-
-  let condition = !isCurrentDay
-  if (useOld) {
-    condition = tenDaysAgo
-  }
-
-  if (condition) {
-    // 不是当天,则使用正常日期显示
-    const originDate = new Date(originTimeStamp)
-    const nowDate = new Date()
-    // 是否同年
-    const sameYear = originDate.getFullYear() === nowDate.getFullYear()
-    // 如果是当年,则不显示年
-    const patternString = sameYear ? 'MM-dd' : 'yyyy-MM-dd'
-    timeString = dateFormatter(originDate, patternString)
-  } else {
-    for (let i = 0; i < dataMap.number.length; i++) {
-      const inm = Math.floor(diffTimeStampAbsS / dataMap.number[i])
-      if (inm !== 0) {
-        timeString = inm + dataMap.zh[i] + postfix
-        break
-      }
-    }
-  }
-  return timeString
-}
-
-/*
-* 时间格式化函数(将时间格式化为,2019年08月12日,2019-08-12,2019/08/12的形式)
-*   pattern参数(想要什么格式的数据就传入什么格式的数据)
-*     · 'yyyy-MM-dd'  ---> 输出如2019-09-20
-*     · 'yyyy-MM-dd HH:mm'  --->  输出如2019-09-20 18:20
-*     · 'yyyy-MM-dd HH:mm:ss'  --->  输出如2019-09-20 06:20:23
-*     · 'yyyy/MM/dd'  --->  输出如2019/09/20
-*     · 'yyyy年MM月dd日'  --->  输出如2019年09月20日
-*     · 'yyyy年MM月dd日 HH时mm分'  --->  输出如2019年09月20日 18时20分
-*     · 'yyyy年MM月dd日 HH时mm分ss秒'  --->  输出如2019年09月20日 18时20分23秒
-*     · 'yyyy年MM月dd日 HH时mm分ss秒 EE'  --->  输出如2019年09月20日 18时20分23秒 周二
-*     · 'yyyy年MM月dd日 HH时mm分ss秒 EEE'  --->  输出如2019年09月20日 18时20分23秒 星期二
-*  参考: https://www.cnblogs.com/mr-wuxiansheng/p/6296646.html
-*/
-function dateFormatter (date, fmt = 'yyyy-MM-dd HH:mm:ss') {
-  // 将传入的date转为时间对象
-  if (!date) return ''
-  date = new Date(date)
-  const o = {
-    'y+': date.getFullYear(),
-    'M+': date.getMonth() + 1, // 月份
-    'd+': date.getDate(), // 日
-    // 12小时制
-    'h+': date.getHours() % 12 === 0 ? 12 : date.getHours() % 12, // 小时
-    // 24小时制
-    'H+': date.getHours(), // 小时
-    'm+': date.getMinutes(), // 分
-    's+': date.getSeconds(), // 秒
-    'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
-    S: date.getMilliseconds(), // 毫秒
-    'E+': date.getDay() // 周
-  }
-  const week = ['日', '一', '二', '三', '四', '五', '六']
-
-  if (/(y+)/.test(fmt)) {
-    fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
-  }
-  if (/(E+)/.test(fmt)) {
-    fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? '星期' : '周') : '') + week[date.getDay()])
-  }
-  for (const k in o) {
-    if (new RegExp('(' + k + ')').test(fmt)) {
-      fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
-    }
-  }
-  return fmt
-}
-
-export { replaceKeyword, dateFromNow }