Browse Source

无用文件删除

Xiao_123 1 week ago
parent
commit
63da7a4aa0
100 changed files with 2129 additions and 11392 deletions
  1. 21 21
      App.vue
  2. 0 161
      components/FilterList/index.vue
  3. 0 354
      components/FilterList/mFilter.vue
  4. 0 101
      components/FilterList/select.vue
  5. 0 431
      components/PositionList/index.vue
  6. 0 301
      components/positionItem/components/baseInfo.vue
  7. 0 92
      components/positionItem/components/extend.vue
  8. 0 234
      components/positionItem/components/portrait.vue
  9. 0 246
      components/positionItem/components/requirement.vue
  10. 0 226
      components/positionItem/components/tableItems.vue
  11. 0 218
      components/positionItem/index.vue
  12. 28 0
      components/uni-calendar/changelog.md
  13. 546 0
      components/uni-calendar/components/uni-calendar/calendar.js
  14. 12 0
      components/uni-calendar/components/uni-calendar/i18n/en.json
  15. 8 0
      components/uni-calendar/components/uni-calendar/i18n/index.js
  16. 12 0
      components/uni-calendar/components/uni-calendar/i18n/zh-Hans.json
  17. 12 0
      components/uni-calendar/components/uni-calendar/i18n/zh-Hant.json
  18. 206 0
      components/uni-calendar/components/uni-calendar/uni-calendar-item.vue
  19. 568 0
      components/uni-calendar/components/uni-calendar/uni-calendar.vue
  20. 360 0
      components/uni-calendar/components/uni-calendar/util.js
  21. 85 0
      components/uni-calendar/package.json
  22. 103 0
      components/uni-calendar/readme.md
  23. 0 54
      custom-tab-bar/index.js
  24. 0 4
      custom-tab-bar/index.json
  25. 0 14
      custom-tab-bar/index.wxml
  26. 0 74
      custom-tab-bar/index.wxss
  27. 0 95
      hooks/useDictionaries.js
  28. 0 433
      hooks/useIM.js
  29. 2 2
      main.js
  30. 2 2
      manifest.json
  31. 3 290
      pages.json
  32. 113 0
      pages/drawLots/index.vue
  33. 0 236
      pages/index/communicate.vue
  34. 0 156
      pages/index/components/condition.vue
  35. 0 115
      pages/index/components/recommend.vue
  36. 0 144
      pages/index/components/talentItem.vue
  37. 0 199
      pages/index/jobFair.vue
  38. 0 56
      pages/index/loading.vue
  39. 0 236
      pages/index/my.vue
  40. 0 280
      pages/index/position.vue
  41. 0 131
      pages/index/search.vue
  42. 0 483
      pages/index/welfare.vue
  43. 48 0
      pages/loading/index.vue
  44. 0 200
      pages/register/contact.vue
  45. 0 220
      pages/register/index.vue
  46. 0 155
      pages/register/phoneValidate.vue
  47. 0 158
      pages/register/review.vue
  48. 0 743
      pagesA/chart/index.vue
  49. 0 68
      pagesA/editPassword/index.vue
  50. 0 107
      pagesA/forgotPassword/index.vue
  51. 0 68
      pagesA/interview/attended.vue
  52. 0 68
      pagesA/interview/cancel.vue
  53. 0 270
      pagesA/interview/components/item.vue
  54. 0 68
      pagesA/interview/feedback.vue
  55. 0 166
      pagesA/interview/index.vue
  56. 0 186
      pagesA/resume/index.vue
  57. 0 406
      pagesA/resume/item.vue
  58. 0 208
      pagesB/CompanyInfoEdit/index.vue
  59. 0 195
      pagesB/InviteInterview/index.vue
  60. 0 36
      pagesB/agreement/CopyrightPolicy.vue
  61. 0 102
      pagesB/agreement/UserBehaviorNorms.vue
  62. 0 27
      pagesB/agreement/WorkplaceCommunityPolicy.vue
  63. 0 44
      pagesB/agreement/index.vue
  64. 0 51
      pagesB/agreement/privacy.vue
  65. 0 78
      pagesB/agreement/user.vue
  66. 0 64
      pagesB/contactUs/index.vue
  67. 0 16
      pagesB/jobFair/addJob.vue
  68. 0 266
      pagesB/jobFair/details.vue
  69. 0 21
      pagesB/jobFair/editJob.vue
  70. 0 237
      pagesB/jobFair/jobFairEntShare.vue
  71. 0 203
      pagesB/jobFair/jobItem.vue
  72. 0 236
      pagesB/jobFair/join.vue
  73. 0 30
      pagesB/personnelDetails/components/advantage.vue
  74. 0 70
      pagesB/personnelDetails/components/baseInfo.vue
  75. 0 58
      pagesB/personnelDetails/components/eduExp.vue
  76. 0 52
      pagesB/personnelDetails/components/jobIntention.vue
  77. 0 72
      pagesB/personnelDetails/components/trainingExperience.vue
  78. 0 72
      pagesB/personnelDetails/components/workExp.vue
  79. 0 275
      pagesB/personnelDetails/index.vue
  80. 0 9
      pagesB/positionAdd/index.vue
  81. 0 40
      pagesB/positionAdd/select.vue
  82. 0 220
      pagesB/positionDetail/index.vue
  83. 0 23
      pagesB/positionEdit/index.vue
  84. 0 147
      pagesB/staffInfoEdit/index.vue
  85. BIN
      static/img/company-fill.png
  86. BIN
      static/img/company.png
  87. BIN
      static/img/female.png
  88. BIN
      static/img/jobFair-fill.png
  89. BIN
      static/img/jobFair.png
  90. BIN
      static/img/man.png
  91. BIN
      static/img/message-fill.png
  92. BIN
      static/img/message.png
  93. BIN
      static/img/position-fill.png
  94. BIN
      static/img/position.png
  95. BIN
      static/img/search-fill.png
  96. BIN
      static/img/search.png
  97. BIN
      static/img/share-poster.jpg
  98. BIN
      static/img/ticket.png
  99. 0 268
      static/style/position/index.css
  100. 0 0
      static/style/position/index.min.css

+ 21 - 21
App.vue

@@ -2,30 +2,30 @@
 	export default {
 		onLaunch: function() {
 			console.log('App Launch')
-			uni.setStorageSync('firstOpen', true)
+			// uni.setStorageSync('firstOpen', true)
 
-			const updateManager = uni.getUpdateManager();
-			updateManager.onCheckForUpdate(function(res){});
+			// const updateManager = uni.getUpdateManager();
+			// updateManager.onCheckForUpdate(function(res){});
 			
-			updateManager.onUpdateReady(function(res){
-				uni.showModal({
-					title: '更新提示',
-					content:'发现新版本,是否重启应用',
-					success(res) {
-						if(res.confirm) {
-							updateManager.applyUpdate();
-						}
-					}
-				})
-			});
+			// updateManager.onUpdateReady(function(res){
+			// 	uni.showModal({
+			// 		title: '更新提示',
+			// 		content:'发现新版本,是否重启应用',
+			// 		success(res) {
+			// 			if(res.confirm) {
+			// 				updateManager.applyUpdate();
+			// 			}
+			// 		}
+			// 	})
+			// });
 			
-			updateManager.onUpdateFailed(function(res) {
-				//新本版下载失败
-				uni.showModal({
-					title:'失败提示',
-					content:'新版本下载失败,请手动删掉小程序后重新搜索进入小程序'
-				})
-			})
+			// updateManager.onUpdateFailed(function(res) {
+			// 	//新本版下载失败
+			// 	uni.showModal({
+			// 		title:'失败提示',
+			// 		content:'新版本下载失败,请手动删掉小程序后重新搜索进入小程序'
+			// 	})
+			// })
 		},
 		onShow: function() {
 			console.log('App Show')

+ 0 - 161
components/FilterList/index.vue

@@ -1,161 +0,0 @@
-<template>
-  <view class="labelColor itemBox" style="height: 45px; z-index: 1; position: relative;">
-    <view class="item" v-for="(item) in filterList" :key="item[props.idValue]">
-      <m-filter
-        :items="item.array"
-        :label="item.label"
-        :value="item.value"
-        :multiple="item.multiple"
-        :item-label="item.itemLabel"
-        :item-value="item.itemValue"
-		    :style="{ 'width': labelWidth }"
-        class="itemFilter default-text-color default-border"
-        :popupStyle="{ 'padding-bottom': paddingBottom + 'px' }"
-        @change="($event, $name) => handleClick($event, $name, item)"
-      >
-        <view
-          :class="(item.multiple && item.value?.length) || (!item.multiple && item.value) ? 'active' : ''"
-          class="name"
-        >
-          <view class="over">
-            {{ item.name ?? item.label }}
-          </view>
-          <template v-if="item.multiple && item.value?.length > 1">
-            <uni-icons
-              class="point"
-              type="smallcircle-filled"
-              color="#00B760"
-              size="6"
-            />
-            {{item.value.length}}
-          </template>
-          <uni-icons
-            type="down"
-            color=""
-            size="12"
-          />
-        </view>
-      </m-filter>
-    </view>
-  </view>
-</template>
-
-<script setup>
-import { ref, watch } from 'vue'
-import { getDict } from '@/hooks/useDictionaries'
-import MFilter from './mFilter.vue'
-import { formatName } from '@/utils/getText'
-
-const emit = defineEmits(['change'])
-const props = defineProps({
-  list: { type: Array, default: () => [] },
-  idValue: { type: String, default: 'id' },
-  labelValue: { type: String, default: 'label' },
-  lazy: { type: Boolean, default: false },
-  paddingBottom: { type: [Number, String], default: 80 },
-  labelWidth: { type: String, default: '100%' }
-})
-
-
-const handleClick = (e, name, item) => {
-  item.value = e
-  item.name = name ?? item.label
-  emit('change', item.key, e)
-}
-
-// 获取字典数据
-const getData = (e) => {
-  if (e?.dictType) {
-    getDict(e.dictType, e.map ? {} : null, e.map ? e.dictType : 'dict').then(({ data }) => {
-      e.array = data.data
-      e.itemLabel = e.map?.text
-      e.itemValue = e.map?.value
-      e.value = e.multiple ? [] : null
-    })
-  }
-  if (e?.items) e.array = e.items
-  if (e?.api) {
-    e.api({ exTime: 1 }).then(({ data }) => {
-      e.array = data.map(k => {
-        const label = e.isFormatText ? formatName(k[e.dataLabel]) : k[e.dataLabel]
-        return { label, value: k[e.dataValue] }
-      })
-    })
-  }
-}
-
-const setItemSelectData = () => {
-  filterList.value.forEach(e => {
-    getData(e)
-  })
-}
-
-// clone list
-const filterList = ref([])
-watch(() => props.list, 
-  (newVal) => {
-    if (!newVal) {
-      filterList.value = []
-      return
-    }
-    filterList.value = newVal
-    
-    if (!props.lazy) {
-      setItemSelectData()
-    }
-  },
-  { immediate: true }
-)
-
-</script>
-
-<style scoped lang="scss">
-.labelColor { color: #5c5c5c; }
-.itemBox {
-  display: flex;
-  justify-content: space-between;
-  .item {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    flex: 1;
-    width: 0;
-    font-size: 14px;
-    margin-right: 10rpx;
-    &:last-child {
-      margin-right: 0 !important;
-    }
-    .itemFilter {
-      width: 100%;
-      border-radius: 15rpx;
-      height: 60rpx;
-      line-height: 60rpx;
-      
-      font-weight: 500;
-      font-size: 22rpx;
-      font-style: normal;
-      text-transform: none;
-    }
-    .name {
-      width: 100%;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      &.active {
-        color: #00B760;
-      }
-      .over {
-        overflow: hidden;
-        white-space: nowrap;
-      }
-      .point {
-        margin: 0 5px;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-      }
-    }
-  }
-}
-.default-border { border: 1px solid #E1E4E9; }
-</style>

+ 0 - 354
components/FilterList/mFilter.vue

@@ -1,354 +0,0 @@
-<template>
-  <view>
-    <view @tap="handleOpen">
-      <slot></slot>
-    </view>
-    <uni-popup ref="popup">
-      <view class="popup-content" :style="props.popupStyle">
-        <view class="popup-content-label">
-          <view class="popup-content-label-item active">{{ label }}</view>
-        </view>
-        <view class="popup-content-body">
-          <view v-for="(arr, i) in showList" :key="i" class="popup-content-body-list">
-            <!-- <view class="popup-content-body-list-label" :class="active === i ? 'active' : ''">{{ arr.label }}</view> -->
-            <view class="popup-content-body-list-items">
-              <view class="content">
-                <view
-                  v-for="_arr in arr.data"
-                  :key="_arr[props.itemValue]"
-                  class="py-1 dFlex"
-                  :class="arr.choose === _arr[props.itemValue] || (Array.isArray(arr.choose) && arr.choose.includes(_arr[props.itemValue]))? 'active' : ''"
-                  @tap="handleNext(_arr, i)"
-                >
-                  {{ _arr[props.itemLabel] }}
-                  <uni-icons
-                    v-if="Array.isArray(arr.choose) && arr.choose.includes(_arr[props.itemValue])"
-                    type="checkmarkempty"
-                    color="#00B760"
-                    size="16"
-                  />
-                </view>
-              </view>
-            </view>
-          </view>
-        </view>
-        <view class="popup-content-footer">
-          <button class="btn cancel" @tap="reset">重置</button>
-          <button class="btn submit" @tap="submit">确定</button>
-        </view>
-      </view>
-    </uni-popup>
-  </view>
-</template>
-
-<script setup>
-import { ref, watch } from 'vue'
-
-const emit = defineEmits(['change', 'init'])
-const props = defineProps({
-  popupStyle: {
-    type: [String, Object],
-    default: ''
-  },
-  value: {
-    type: [String, Array, Number, Object],
-    default: null
-  },
-  items: {  // 树结构
-    type: Array,
-    default: () => []
-  },
-  label: {
-    type: String,
-    default: ''
-  },
-  multiple: {
-    type: Boolean,
-    default: false
-  },
-  itemLabel: {
-    type: String,
-    default: 'label'
-  },
-  itemValue: {
-    type: String,
-    default: 'value'
-  },
-  children: {
-    type: String,
-    default: 'children'
-  }
-})
-
-const popup = ref()
-const showList = ref([])
-
-watch(
-  () => props.items,
-  (val) => {
-    // 初始化赋值
-    showList.value = [{
-      choose: -1,
-      data: val
-    }]
-  },
-  {
-    immediate: true,
-    deep: true
-  }
-)
-
-const handleData = (val) => {
-  if (!val) {
-      showList.value = [{
-        choose: -1,
-        data: props.items
-      }]
-      return
-    }
-    // 单选 设置回显
-    if (!props.multiple) {
-      const item = findItem(val, props.items)
-      if (!item) {
-        showList.value = [{
-          choose: -1,
-          data: props.items
-        }]
-        return
-      }
-      showList.value = item.map(e => {
-        return {
-          choose: e[props.itemValue],
-          data: e.data
-        }
-      })
-      emit('init', item[item.length - 1][props.itemLabel])
-      return
-    }
-    if (!Array.isArray(val)) {
-      showList.value = [{
-        choose: -1,
-        data: props.items
-      }]
-      return
-    }
-    // 多选 设置回显
-    const arr = []
-    const label = []
-    val.forEach(e => {
-      const item = findItem(e, props.items)
-      if (!item) {
-        return
-      }
-      label.push(item[item.length - 1][props.itemLabel])
-      if (!arr.length) {
-        arr.push(...item.map((e, i) => {
-          return {
-            choose: i === item.length - 1 ? [e[props.itemValue]] : e[props.itemValue],
-            data: e.data
-          }
-        }))
-        return
-      }
-      arr[arr.length - 1].choose.push(item[item.length - 1][props.itemValue])
-    })
-    if (!arr.length) {
-      showList.value = [{
-        choose: -1,
-        data: props.items
-      }]
-      return
-    }
-    showList.value = arr
-    emit('init', label)
-}
-
-const findItem = (value, lists) => {
-  let level = -1
-  return check(value, lists)
-  function check (val, items, arr = []) {
-    let i = 0
-    level++
-    while (i < items.length) {
-      arr[level] = {
-        ...items[i],
-        data: items
-      }
-      if (items[i][props.itemValue] === val) {
-        return arr
-      }
-      if (items[i][props.children] && items[i][props.children].length > 0) {
-        const data = check(val, items[i][props.children], arr)
-        if (data) {
-          return data
-        }
-      }
-      i++
-    }
-    level--
-    return false
-  }
-}
-
-const handleOpen = () => {
-  // 无数据时不弹出
-  if (!props.items || !props.items.length) {
-    uni.showToast({
-      title: `${props.label}暂无数据`,
-      icon: 'none',
-      duration: 2000
-    })
-    return
-  }
-  
-  handleData(props.value)
-  popup.value.open('bottom')
-}
-
-const handleNext = (item, index) => {
-  const _i = index + 1
-  // active.value = _i
-  showList.value.splice(_i, showList.value.length - _i)
-  showList.value[index].label = item[props.itemLabel]
-  if (item[props.children] && item[props.children].length) {
-    showList.value[index].choose = item[props.itemValue]
-    showList.value.push({
-      choose: -1,
-      data: item[props.children]
-    })
-    return
-  }
-  if (!props.multiple) {
-    showList.value[index].choose = item[props.itemValue]
-    return
-  }
-  if (!Array.isArray(showList.value[index].choose)) {
-    showList.value[index].choose = [item[props.itemValue]]
-    return
-  }
-  if (!showList.value[index].choose.includes(item[props.itemValue])) {
-    showList.value[index].choose.push(item[props.itemValue])
-    return
-  }
-  const _index = showList.value[index].choose.indexOf(item[props.itemValue])
-  showList.value[index].choose.splice(_index, 1)
-}
-
-const reset = () => {
-  showList.value = [{
-    choose: -1,
-    data: props.items
-  }]
-  emit('change', props.multiple ? [] : null)
-  popup.value.close()
-}
-const submit = () => {
-  const item = showList.value[showList.value.length - 1]
-  if (item.choose === -1) {
-    const _item = showList.value[showList.value.length - 2]
-    if (!item) {
-      emit('change', props.multiple ? [] : null)
-      popup.value.close()
-      return
-    }
-    emit('change', props.multiple ? [_item.choose] : _item.choose, props.multiple ? showList.value[0].label : _item.label, item)
-    popup.value.close()
-    return
-  }
-  emit('change', item.choose, props.multiple ? showList.value[0].label : item.label, item)
-  popup.value.close()
-}
-
-</script>
-
-<style lang="scss" scoped>
-.popup-content {
-  height: 580px;
-  background: #FFF;
-  border-radius: 20rpx 20rpx 0 0;
-  padding: 10px;
-  box-sizing: border-box;
-  display: flex;
-  flex-direction: column;
-  &-label {
-    height: 50px;
-    display: flex;
-    font-size: 32rpx;
-    font-weight: bold;
-    margin-bottom: 10px;
-    border-bottom: 2rpx solid #EEE;
-    &-item {
-      display: flex;
-      align-items: center;
-      padding: 0 15px;
-      box-sizing: border-box;
-      &.active {
-        border-bottom: 2px solid #00B760;
-      }
-    }
-  }
-  &-body {
-    flex: 1;
-    height: 0;
-    display: flex;
-    &-list {
-      height: 100%;
-      min-width: 100px;
-      margin-right: 20px;
-      display: flex;
-      flex-direction: column;
-      &-label {
-        border-bottom: 1px solid #eee;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        height: 50px;
-        box-sizing: border-box;
-        margin-bottom: 10px;
-        &.active {
-          border-bottom: 2px solid #00B760;
-        }
-      }
-      &-items {
-        flex: 1;
-        height: 0;
-        .content {
-          height: 100%;
-          overflow-x: hidden;
-          overflow-y: auto;
-          .active {
-            color: #00B760;
-          }
-        }
-      }
-    }
-  }
-  &-footer {
-    height: 50px;
-    display: flex;
-    align-items: center;
-    .btn {
-      font-size: 28rpx;
-      height: 30px;
-      line-height: 30px;
-      &.cancel {
-        width: 40%;
-        margin-right: 10px;
-      }
-      &.submit {
-        flex: 1;
-        background: #00B760;
-        color: #FFF ;
-      }
-    }
-  }
-}
-.dFlex {
-  display: flex;
-  justify-content: space-between;
-  // height: 20px;
-}
-.py-1 {
-  padding: 10px 0;
-}
-</style>

+ 0 - 101
components/FilterList/select.vue

@@ -1,101 +0,0 @@
-<template>
-  <m-filter
-    :label="props.label"
-    :items="props.items"
-    :item-label="props.itemLabel"
-    :item-value="props.itemValue"
-    :multiple="props.multiple"
-    :value="showValue"
-    @change="handleChange"
-    @init="handleInit"
-  >
-    <view class="content">
-      <view class="content-cover"></view>
-      <uni-easyinput v-model="showLabel" placeholder="请选择其它感兴趣的城市" :clearable="false"/>
-    </view>
-  </m-filter>
-</template>
-
-<script setup>
-import MFilter from './mFilter'
-import { ref, watch } from 'vue'
-
-const emit = defineEmits(['update:modelValue'])
-const props = defineProps({
-  modelValue: { // 传入值
-    type: [String, Number, Array, Object],
-    default: ''
-  },
-  label: {
-    type: String,
-    default: '请选择'
-  },
-  items: {
-    type: Array,
-    default: () => []
-  },
-  itemLabel: {
-    type: String,
-    default: 'label'
-  },
-  itemValue: {
-    type: String,
-    default: 'value'
-  },
-  multiple: {
-    type: Boolean,
-    default: false
-  }
-})
-// 回显使用id
-const showValue = ref(props.modelValue)
-const showLabel = ref(null)
-
-// const isChange = ref(false)
-watch(
-  () => props.modelValue,
-  (val) => {
-    showValue.value = val
-  },
-  {
-    immediate: true,
-    deep: true
-  }
-)
-
-const handleInit = (val) => {
-  showLabel.value = val
-  console.log('label', val)
-}
-
-const handleChange = (value, label, item) => {
-  console.log(111)
-  if (props.multiple) {
-    if (!value.length) {
-      showLabel.value = null
-      emit('update:modelValue', null)
-      return
-    }
-    showLabel.value = item.data.filter(e => value.includes(e[props.itemValue])).map(e => e[props.itemLabel])
-    emit('update:modelValue', value)
-    return
-  }
-  showLabel.value = label
-  emit('update:modelValue', value)
-}
-
-</script>
-
-<style lang="scss" scoped>
-.content {
-	position: relative;
-	&-cover {
-		position: absolute;
-		width: 100%;
-		height: 100%;
-		left: 0;
-		top: 0;
-		z-index: 3;
-	}
-}
-</style>

+ 0 - 431
components/PositionList/index.vue

@@ -1,431 +0,0 @@
-<template>
-  <view class="ss-m-x-20">
-    <!-- 岗位列表 -->
-    <view v-if="list?.length" class="ss-p-b-30 ss-p-t-20">
-      <view v-for="(item, index) in list" :key="index" class="mList" @click="handleDetail(item)">
-        <view v-if="item?.hrName" class="d-flex align-center item-top">
-          <view class="avatarBox">
-            <image class="enterAvatar" :src="getUserAvatar(item.hrHeadImg)"></image>
-          </view>
-          <view class="ss-m-l-20 label-text">{{ item?.hrName }}</view>
-        </view>
-        <!-- 职位信息 -->
-        <view class="list-shape" style="border-radius: 12px;">
-          <!-- 职位 -->
-          <view class="titleBox my-5">
-            <view style="display: flex;align-items: center;">
-              <image v-if="item.jobFairName" src="/static/svg/jobFair.svg" class=" ss-m-r-10" style="width: 20px; height: 20px;"></image>
-              <rich-text v-if="item.name?.indexOf('style') !== -1" class="job-name" :nodes="item.name"></rich-text>
-              <view v-else class="job-name">{{ formatName(item.name) }}</view>
-            </view>
-            <image v-if="item.top && tab === 1" src="/static/svg/topUp.svg" class="TopUpSvg"></image>
-          </view>
-          <!-- 职位类型 -->
-          <!-- <view class="font-size-13 ellipsis ss-m-5" style="color: #808080;">
-            <span>{{item.positionName }}</span>
-          </view> -->
-          <!-- 薪酬、工作地、学历、工作经验 -->
-          <view class="d-flex align-center justify-space-between">
-            <view class="font-size-13 ellipsis" style="flex: 1;">
-              <span class="tag-gap" style="color: #808080;">
-                <span>{{item.area?.str ?? '全国' }}</span>
-                <span class="divider-mx" v-if="item.eduName">|</span>
-                <span>{{item.eduName }}</span>
-                <span class="divider-mx" v-if="item.expName">|</span>
-                <span>{{item.expName }}</span>
-                <span class="divider-mx">|</span>
-                <span>{{!item.payFrom && !item.payTo ? '面议' : `${item.payFrom}-${item.payTo}${item.payName ? '/' + item.payName : ''}` }}</span>
-              </span>
-            </view>
-          </view>
-          <view class="d-flex font-size-13 color-666">
-            <view class="ss-m-t-10" v-if="tab !== 0">刷新时间:{{ item.refreshTime ? timesTampChange(item.refreshTime, 'Y-M-D h:m') : '暂无' }}</view>
-          </view>
-          <view v-if="item.jobFairName" class="font-size-13 color-primary ss-m-t-10">
-            招聘会:{{ item.jobFairName }}
-          </view>
-          <view class="sub-li-bottom ss-m-t-20">
-            <view 
-              v-if="tab === 0 && jobNum && +jobNum > 0" 
-              class="sub-li-bottom-item color-primary" 
-              style="width: 33%;" 
-              @tap.stop="handleRelease(item)"
-            >使用额度发布</view>
-            <view v-if="tab === 0" class="sub-li-bottom-item color-primary" style="width: 33%;" @tap.stop="toPay(item)">支付发布</view>
-            <view v-if="tab === 0" class="sub-li-bottom-item color-error" style="width: 33%;" @tap.stop="handleDelete(item)">删除</view>
-			
-            <view 
-              v-else 
-              class="sub-li-bottom-item color-primary" 
-              style="width: 45%;" 
-              @tap.stop="handleToResume(item)"
-            >{{ item.count || 0 }} 已投递简历</view>
-            <view 
-              v-if="tab === 1" 
-              class="sub-li-bottom-item"
-			   :class="[`color-${item.jobFairName ? '999' : 'warning'}`]"
-              @tap.stop="handleAction(item.top ? 4 : 3, '', item)"
-            >{{ item.top ? '取消置顶' : '置顶' }}</view>
-            <view v-if="tab === 1" class="sub-li-bottom-item color-error" @tap.stop="handleAction(0, '', item, item)">关闭</view>
-            <view v-if="tab === 2" class="sub-li-bottom-item color-primary" @tap.stop="handleAction(1, '', item, item)">激活</view>
-          </view>
-        </view>
-      </view>
-      <view v-if="props.noMore" class="noMore">暂无更多数据</view>
-    </view>
-    <view v-else>
-      <image src="https://minio.menduner.com/dev/bb43df1dc91945e05ee93da76e49b34f87b0d10203eb76c20e2d4999a13b9a0a.png" mode="widthFix" style="width: 100vw;height: 100vh;"></image>
-      <view style="color: gray; text-align: center;">暂无数据</view>
-    </view>
-    <!-- 确认框 -->
-    <uni-popup ref="confirm" type="dialog">
-      <uni-popup-dialog
-        type="warn"
-        cancelText="取消"
-        confirmText="确认" 
-        title="系统提示"
-        :content="dialogContent"
-        @confirm="handleConfirm"
-        @close="handleClose"
-      ></uni-popup-dialog>
-    </uni-popup>
-    <!-- 支付 -->
-    <payPopup v-if="props.payable" ref="payRef" @paySuccess="paySuccess"></payPopup>
-  </view>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import { timesTampChange } from '@/utils/date'
-import { formatName } from '@/utils/getText'
-import payPopup from '@/components/payPopup'
-import { userStore } from '@/store/user'; const useUserStore = userStore()
-import {
-  topJobAdvertisedCancel,
-  topJobAdvertised,
-  refreshJobAdvertised,
-  closeJobAdvertised,
-  enableJobAdvertised,
-  updatePositionStatus,
-  deletePosition
-} from '@/api/new/position'
-import { getUserAvatar } from '@/utils/avatar'
-
-const emit = defineEmits(['entClick', 'refresh'])
-const props = defineProps({
-  tab: { type: Number, default: 0 },
-  list: { type: Array, default: () => [] },
-  noMore: { type: Boolean, default: false },
-  showWelfareTag: { type: Boolean, default: true },
-  payable: { type: Boolean, default: false },
-  jobNum: { type: Number, default: 0 }
-})
-
-const userInfo = ref(useUserStore?.userInfo || {})
-
-// 使用额度发布职位
-const handleRelease = async (val) => {
-  if (!val.id) return
-  try {
-    await updatePositionStatus(val.id)
-	  uni.showToast({ title: '发布成功', icon: 'success', duration: 2000 })
-    emit('refresh', { reset: true })
-  } catch {}
-}
-
-// 删除待支付职位
-const handleDelete = async (val) => {
-  if (!val.id) return
-  try {
-    await deletePosition(val.id)
-    uni.showToast({ title: '删除成功', icon: 'success', duration: 2000 })
-    emit('refresh', { reset: true })
-  } catch {}
-}
-
-const payRef = ref()
-// 支付
-const toPay = async (val) => {
-  payRef.value && payRef.value.handleOpen({ spuId: val?.id||'', spuName: val?.name||'', price: 1, type: 1 })
-}
-
-const confirm = ref()
-const confirmType = ref('closeJob') // 确认框类型
-const dialogContent = ref('')
-let handleActionInfo = {}
-const apiList = [closeJobAdvertised, enableJobAdvertised, refreshJobAdvertised, topJobAdvertised, topJobAdvertisedCancel]
-// 职位关闭、激活、刷新、置顶
-const handleAction = async (index, type, { id, jobFairName, jobFairId }, item) => {
-	// 招聘会职位激活、关闭跳转去招聘会进行操作
-  if (jobFairName) {
-	  if ([3,4].includes(index)) return uni.showToast({ title: '招聘会职位无法操作', icon: 'none', duration: 2000 })// 招聘会职位置顶、取消置顶不可操作
-    uni.showToast({ title: '该职位属于招聘会,即将前往招聘会', icon: 'none', duration: 2000 })
-    setTimeout(() => {
-      uni.navigateTo({
-        url: `/pagesB/jobFair/details?id=${jobFairId}`
-      })
-    }, 1000)
-    return
-  }
-  const ids = type ? [] : [id]
-  if (!ids?.length && !index) return
-  try {
-    handleActionInfo.ids = ids
-    handleActionInfo.index = index
-    uni.showLoading({ title: '操作中...', mask: true })
-
-    // 关闭职位提醒
-    if (index === 0) {
-      const text = userInfo.value?.entitlement?.publishJobCount && userInfo.value?.entitlement?.publishJobCount > 0 ? '将消耗一个发布点数' : '将重新收取费用'
-      const positionName = item?.name ? '【' + formatName(item?.name) + '】' : '所选'
-      confirmType.value = 'closeJob' // 确认框类型
-      dialogContent.value = `是否确认关闭${positionName}职位?关闭后再激活,${text}!`
-      confirm.value.open()
-      return
-    }
-
-    // 没有可发布额度激活职位需重新付款
-    userInfo.value = await useUserStore.getUserInfos()
-    if (index === 1 && userInfo.value?.entitlement?.publishJobCount-0 <= 0) {
-      toPay(item)
-      return
-    }
-    await apiList[index](ids)
-    emit('refresh', { reset: true })
-    setTimeout(() => { uni.showToast({ title: '操作成功', icon: 'success' }) }, 1000)
-    // 
-  } catch (error) {
-    uni.showToast({ title: '操作失败', icon: 'error', duration: 2000 })
-    console.log(error)
-  } finally {
-    uni.hideLoading()
-  }
-}
-
-const handleClose = () => {
-  confirm.value.close()
-}
-
-// 取消置顶
-// const topUpSvgClickVal = ref({})
-// const topUpSvgClick = (item) => {
-//   topUpSvgClickVal.value = item
-//   confirmType.value = 'topUpJob' // 确认框类型
-//   const positionName = item?.name ? '【' + formatName(item?.name) + '】职位' : '职位'
-//   dialogContent.value = `是否取消置顶${positionName}?`
-//   confirm.value.open()
-// }
-
-const handleConfirm = () => {
-  if (confirmType.value === 'closeJob') closeJob()
-  // if (confirmType.value === 'topUpJob') handleAction(4, '', topUpSvgClickVal.value)
-}
-
-// 关闭职位
-const closeJob = async () => {
-  try {
-    uni.showLoading({ title: '关闭中...', mask: true })
-    await apiList[handleActionInfo?.index](handleActionInfo?.ids)
-    emit('refresh', { reset: true })
-    setTimeout(() => { uni.showToast({ title: '关闭成功', icon: 'success' }) }, 1000)
-  } catch (error) {
-    uni.showToast({ title: '关闭失败', icon: 'error' })
-    console.log(error)
-  } finally {
-    uni.hideLoading()
-  }
-}
-
-// 编辑职位
-// const handleEdit = async (val) => {
-//   if (!val.id || !val.edit) {
-//     uni.showToast({ title: '职位发布时间超过24小时的不支持编辑', icon: 'none', duration: 2000 })
-//     return
-//   }
-//   uni.navigateTo({ url: `/pagesB/positionEdit/index?jobId=${val.id}` })
-// }
-
-// 职位详情
-const handleDetail = (item) => {
-  if (!item.id) return
-  let url = `/pagesB/positionDetail/index?jobId=${item.id}&isEdit=${item.edit}`
-  if (item.jobFairName) url += `&jobFairId=${item.jobFairId}&fairNoEdit=true`
-  uni.navigateTo({ url })
-}
-
-// 查看职位投递简历
-const handleToResume = (val) => {
-  let url = `/pagesA/resume/index?jobId=${val.id}&jobName=${formatName(val.name)}`
-  if (val.jobFairId) url += `&jobFairId=${val.jobFairId}`
-  uni.navigateTo({ url })
-}
-
-const paySuccess = () => {
-  emit('refresh', { reset: true })
-  setTimeout(() => { uni.showToast({ title: '发布成功', icon: 'success', duration: 2000 }) }, 1000)
-}
-
-</script>
-
-<style scoped lang="scss">
-.avatarBox {
-  max-width: 60rpx;
-  max-height: 60rpx;
-}
-.item-top {
-  padding: 20rpx 30rpx;
-  background: linear-gradient(90deg,#f5fcfc,#fcfbfa);
-  border-radius: 12px 12px 0 0;
-  font-size: 28rpx;
-  color: #0E100F;
-  .label-text {
-	  max-width: 100%;
-	  text-overflow: ellipsis;
-	  white-space: nowrap;
-	  overflow: hidden;
-  }
-}
-.noMore{
-  margin: 20px 0;
-}
-
-.date-time{
-  color:#d9d0d2;
-  float: right;
-}
-
-.divided-line {
-  width: 100%;
-  height: 1px;
-  background-color: #f0f2f7;
-  margin: 20px 0;
-
-}
-.enterAvatar{
-	width: 60rpx;
-	height: 60rpx;
-	margin: auto;
-  border-radius: 50%;
-}
-
-.job-name {
-  font-size: 16px;
-  font-weight: 700;
-  color: #0E100F;
-  max-width: 80vw;
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-}
-
-
-.salary-text {
-	float: right;
-	color: #00B760;
-  font-weight: 700;
-}
-.list-shape {
-	padding: 10px 30rpx 10px;
-  border-radius: 12px 12px 0 0;
-  .titleBox {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-  }
-}
-.tag-gap{
-	margin: 10rpx 10rpx 10rpx 0;
-}
-.tag-gap1{
-  margin-bottom: 20px;
-}
-.divider-mx{
-	margin: 0 10rpx;
-}
-.divider {
-	color:#e4d4d2;
-}
-
-//公司名称
-.cer-end{
-  position: absolute;
-  top: 85%;
-  right: 16%;
-}
-.cer-text{
-  text-decoration: underline;
-  margin: 0 5rpx;
-}
-//一行展示不全...
-.dis{
-	display: flex;
-	align-items: center;
-}
-.mList {
-  margin-bottom: 20rpx;
-  position: relative;
-  box-shadow: 1px 2px 12px rgba(0, 0, 0, 0.17);
-  border-radius: 20rpx;
-  background-color: #fbfbfb;
-}
-/* 列表触底暂无更多 */
-.noMore{ text-align:center; color:grey; }
-.mt { margin-top: 15rpx; }
-.mb { margin-bottom: 10rpx; }
-.ml { margin-left: 20rpx; }
-.mr { margin-right: 20rpx; }
-.mr-10{ margin-right: 10rpx; }
-.my-5{ margin: 5px 0; }
-.disable {
-  position: relative;
-  overflow: hidden;
-  &::after {
-    content: '已失效';
-    position: absolute;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    font-size: 1.2em;
-    font-weight: bold;
-    color: #fc796f;
-    top: 0;
-    border-radius: 12px;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    background-color: rgba(255, 255, 255, 0.75);
-  }
-}
-.resumeCount {
-  color: #00B760;
-  font-size: 12px;
-  margin: 0 10px;
-}
-
-.sub-li-bottom {
-  display: flex;
-  justify-content: flex-end;
-  margin-top: 10px;
-  font-size: 13px;
-  color: #666;
-	&-item {
-		width: 25%;
-		height: 35px;
-		line-height: 35px;
-		text-align: center;
-		margin-right: 15px;
-		background-color: #f7f8fa;
-		border-radius: 4px;
-		&:last-child {
-			margin-right: 0;
-		}
-	}
-}
-.TopUpSvg {
-  width: 45px;
-  height: 45px;
-  position: absolute;
-  top: -3px;
-  right: -4px;
-}
-</style>

+ 0 - 301
components/positionItem/components/baseInfo.vue

@@ -1,301 +0,0 @@
-<template>
-	<view class="wrapper">
-		<uni-forms ref="form" :modelValue="formData" :rules="rules" validateTrigger="bind" label-width="90px" label-align="right">
-			<uni-forms-item label="职位类型" name="positionId" required>
-        <view class="positionTemplate">
-          <uni-data-picker class="picker" popup-title="请选择职位类型" v-model="formData.positionId" :localdata="dictObj?.positionTreeData || []" :clear-icon="false" :map="{ text: 'nameCn', value: 'id'}"></uni-data-picker>
-          <button v-if="formData.positionId" class="btn" type="primary" size="mini" @click="useJobTemplate">职位模板</button>
-        </view>
-			</uni-forms-item>
-			<uni-forms-item required label="职位名称" name="name">
-        <uni-easyinput v-model="formData.name" placeholder="请填写职位名称" @blur="handleValidName"></uni-easyinput>
-			</uni-forms-item>
-      <!-- <template v-if="!props.isFair && jobFairList?.length">
-        <uni-forms-item label="招聘会" name="bizId" >
-          <view style="max-width: calc(100vw - 110px);">
-            <uni-data-picker class="picker" popup-title="请选择招聘会" v-model="formData.bizId" :localdata="jobFairList" :clear-icon="false" :map="{ text: 'title', value: 'id'}"></uni-data-picker>
-          </view>
-          <view style="color: #777; font-size: 12px;" class="ss-m-t-8 ss-m-l-10">发布的职位会在对应的招聘会显示</view>
-        </uni-forms-item>
-      </template> -->
-      <!-- <uni-forms-item label="到期时间" name="expireTime" required>
-				<view class="d-flex">
-          <picker mode="date" :value="formData.expireTime" :disabled="expireTimeDisabled" :start="startDate" @change="expireTimeChange">
-            <view class="uni-input ss-m-t-20" :style="{'opacity': expireTimeDisabled ? '0.5' : '1'}">{{ formData.expireTime }}</view>
-          </picker>
-          <uni-data-checkbox selectedColor="#00B760" class="ss-m-l-50 ss-m-t-14" multiple v-model="soFar" :localdata="[{ text: '长期有效', value: 1 }]" @change="handleChangeSofar"></uni-data-checkbox>
-        </view>
-			</uni-forms-item> -->
-      <uni-forms-item label="岗位职责" name="content" required>
-        <RichEditor ref="contentRef" :richValue="formData.content" @blur="val => editorBlur('content', val)" :max="5000" />
-			</uni-forms-item>
-      <uni-forms-item label="岗位要求 " name="requirement" required>
-        <RichEditor ref="requirementRef" :richValue="formData.requirement" @blur="val => editorBlur('requirement', val)" :max="5000" />
-			</uni-forms-item>
-		</uni-forms>
-    <!-- 确认框 -->
-    <uni-popup ref="confirm" type="dialog">
-      <uni-popup-dialog
-        type="warn"
-        cancelText="取消"
-        confirmText="确认"
-        title="系统提示"
-        content="您确定要放弃目前岗位描述的内容吗?"
-        @confirm="handleConfirm"
-        @close="handleClose"
-      ></uni-popup-dialog>
-    </uni-popup>
-    <!-- 确认框 -->
-    <uni-popup ref="validRef" type="dialog">
-      <uni-popup-dialog
-        type="warn"
-        cancelText="继续发布"
-        confirmText="查看已有职位"
-        title="系统提示"
-        content="该职位名称已在您的招聘职位列表中存在,是否继续发布?"
-        @confirm="handleOpen"
-        @close="handleCancel"
-      ></uni-popup-dialog>
-    </uni-popup>
-    <uni-popup ref="tableRef" type="share" safeArea backgroundColor="#fff">
-      <div class="dialog-content">
-        <view class="dialog-close" @tap.stop="closeClick">
-          <view class="dialog-close-plus"></view>
-          <view class="dialog-close-plus dialog-close-rotate"></view>
-        </view>
-        <div class="table">
-          <tablePage :list="tableItems"></tablePage>
-        </div>
-      </div>
-    </uni-popup>
-	</view>
-</template>
-<script setup>
-import { ref, unref } from 'vue'
-import { dictObj } from '@/utils/position.js'
-// import { getNextDate } from '@/utils/date'
-import { getRecruitPositionDetails } from '@/api/new/position'
-// import { dateToTimestamp } from '@/utils/date.js'
-import { getJobFairWhiteList } from '@/api/jobFair'
-import RichEditor from '@/components/RichEditor'
-import { dealDictArrayData } from '@/utils/position'
-import { getJobAdvertised } from '@/api/search'
-import tablePage from './tableItems.vue'
-const props = defineProps({
-  data: {
-    type: Object,
-    default: () => {}
-  },
-  isFair: {
-    type: Boolean,
-    default: false
-  }
-})
-
-const formData = ref({
-  bizId: props.data?.bizId || '',
-  positionId: props.data?.positionId || '',
-  name: props.data?.name || '', //  + '测试' + new Date().getTime().toString()
-  // expireTime: props.data?.expireTime || getNextDate(15, 'YYYY-MM-DD', 'day'),
-  content: props.data?.content || '',
-  requirement: props.data?.requirement || ''
-})
-
-// const startDate = new Date().getFullYear() + '-' + (new Date().getMonth() + 1) // 不可选时间
-// const expireTimeDisabled = ref(props.data?.expireTime === null ? true : false)
-// 至今
-// const handleChangeSofar = (e) => {
-//   const value = e.detail.value.length ? e.detail.value[0] : ''
-//   expireTimeDisabled.value = value ? true : false
-// }
-// const expireTimeChange = (e) => {
-//   formData.value.expireTime = e?.detail?.value
-// }
-
-const rules = {
-	positionId:{
-		rules: [{required: true, errorMessage: '请选择职位类型' }]
-	},
-	positionId:{
-		rules: [{required: true, errorMessage: '请选择职位类型' }]
-	},
-	name:{
-		rules: [{required: true, errorMessage: '请填写职位名称' }]
-	},
-	// expireTime:{
-	// 	rules: [{required: true, errorMessage: '请选择职位到期时间' }]
-	// },
-	content:{
-		rules: [{required: true, errorMessage: '请填写岗位职责' }]
-	},
-	requirement:{
-		rules: [{required: true, errorMessage: '请填写岗位要求' }]
-	},
-}
-
-const editorBlur = (key, val) => {
-  formData.value[key] = val || ''
-}
-
-// 获取企业已加入的招聘会列表
-// const jobFairList = ref(false)
-// const getJobFairData = async () => {
-//   if (props.isFair) return
-//   const res = await getJobFairWhiteList()
-//   jobFairList.value = res?.data || []
-//   if (formData.value.bizId) {
-//     if (!jobFairList.value?.length) {
-//       formData.value.bizId = '' // 企业已经不在任何招聘会白名单中
-//       return
-//     }
-//     const jobFairItem = jobFairList.value.find(e => e.id === formData.value.bizId)
-//     if (!jobFairItem) formData.value.bizId = '' // 招聘会已经关闭 或者已被移除招聘会白名单
-//   }
-// }
-// getJobFairData()
-
-const pushTemplate = () => {
-  formData.value.content = jobTemplateRes.value.content
-  formData.value.requirement = jobTemplateRes.value.requirement
-  uni.showToast({ title: '模板填充完成!', icon: 'success' })
-}
-
-const confirm = ref()
-const handleClose = () => {
-  confirm.value.close()
-}
-const handleConfirm = () => {
-  try {
-    uni.showLoading({ title: '替换中...', mask: true })
-    pushTemplate()
-  } catch (error) {
-    uni.showToast({ title: '替换失败', icon: 'error' })
-    console.log(error)
-  } finally {
-    uni.hideLoading()
-  }
-}
-
-const jobTemplateRes = ref({})
-const useJobTemplate = async () => {
-  if (!formData.value.positionId) return Snackbar.warning('请先选择职位类型')
-  // 获取职位模板内容-赋值
-  const res = await getRecruitPositionDetails(formData.value.positionId)
-  if (!res?.data || !res.data .content || !res.data.requirement) {
-    uni.showToast({ title: '此职位类型没有可使用的模板!', icon: 'none', duration: 2000 })
-    return
-  }
-  jobTemplateRes.value = res.data
-  if (formData.value?.content || formData.value?.requirement) {
-    // 弹窗提示
-    confirm.value.open()
-  } else {
-    // 无内容点击默认填充
-    pushTemplate()
-  }
-}
-
-const closeClick = () => {
-  tableRef.value.close()
-}
-
-const validRef = ref()
-const tableRef = ref()
-const handleCancel = () => {
-  validRef.value.close()
-}
-const handleOpen = () => {
-  tableRef.value.open()
-}
-
-// 效验职位名称是否重复
-const tableItems = ref([])
-const handleValidName = async () => {
-  if (!formData.value.name) return
-  try {
-    const { data } = await getJobAdvertised({ jobName: formData.value.name })
-    tableItems.value = data ? dealDictArrayData([], data) : []
-    if (data && data.length > 0) {
-      // 弹窗提示
-      validRef.value.open()
-    }
-  } catch {}
-}
-
-const form = ref()
-const contentRef = ref()
-const requirementRef = ref()
-// const soFar = ref(props.data?.expireTime === null ? [1] : [])
-const getQuery = async () => {
-  const valid = await unref(form).validate()
-  if (!valid) return
-
-  const obj = {
-    hirePrice: 0,
-    // soFar: Boolean(soFar.value?.length),
-    hire: false,
-    expireTime: null,
-    ...formData.value
-  }
-
-  // obj.source = props.isFair ? '2' : '0' // 职位来源(0职位管理|1众聘职位|2招聘会)
-  // obj.expireTime = obj.soFar ? null : dateToTimestamp(obj.expireTime)
-  obj && Object.keys(obj).length && Object.keys(obj).forEach(key => { 
-    if (['areaId', 'eduType', 'expType'].includes(key) && obj[key] === -1)  obj[key] = null 
-  })
-
-  return obj
-}
-
-defineExpose({
-  getQuery
-})
-
-</script>
-
-<style lang="scss" scoped>
-.positionTemplate {
-  text-align: left;
- .btn {
-  width: 90px;
-  line-height: 34px;
-  margin-top: 10px;
- }
-}
-
-.dialog-content {
-  height: 70vh;
-  overflow-y: hidden;
-  padding-top: 45px;
-  .table {
-    height: 100%;
-    overflow-y: auto;
-  }
-  .dialog-close {
-    position: absolute;
-    top: 0;
-    right: 0;
-    height: 24px;
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-    padding: 0 25px;
-    margin-top: 10px;
-    z-index: 1;
-    .dialog-close-plus {
-      width: 16px;
-      height: 2px;
-      background-color: #737987;
-      border-radius: 2px;
-      transform: rotate(45deg);
-    }
-    
-    .dialog-close-rotate {
-      position: absolute;
-      transform: rotate(-45deg);
-    }
-  }
-}
-
-
-</style>

+ 0 - 92
components/positionItem/components/extend.vue

@@ -1,92 +0,0 @@
-<!--  -->
-<template>
-	<view class="f-straight wrapper">
-		<uni-forms ref="form" :modelValue="formData" validateTrigger="bind" label-width="90px" label-align="right">
-			<uni-forms-item label="招聘部门" name="dept">
-        <uni-easyinput v-model="formData.dept" placeholder="请填写招聘部门"></uni-easyinput>
-			</uni-forms-item>
-			<uni-forms-item label="专业要求" name="majorName">
-				<uni-combox placeholder="请选择专业要求" v-model="majorName" :candidates="majorData" @input="handleSearchMajor"></uni-combox>
-        <!-- <uni-easyinput v-model="formData.dept" placeholder="请选择专业要求" @focus="majorFocus"></uni-easyinput> -->
-			</uni-forms-item>
-			<uni-forms-item label="工作频率" name="dateType">
-				<uni-data-picker popup-title="请选择工作频率" v-model="formData.dateType" :localdata="dateTypeArr" :clear-icon="false" :map="{ text: 'label', value: 'value'}"></uni-data-picker>
-			</uni-forms-item>
-			<uni-forms-item label="出勤天数" name="frequendayay">
-        <uni-number-box v-model="formData.day" :width="100"></uni-number-box>
-			</uni-forms-item>
-		</uni-forms>
-	</view>
-</template>
-<script setup>
-import { ref } from 'vue'
-import { schoolMajorByName, schoolMajorById } from '@/api/resume'
-const props = defineProps({
-  data: {
-    type: Object,
-    default: () => {}
-  }
-})
-
-const formData = ref({
-  dept: props.data?.dept || '',
-  dateType: props.data?.frequency?.dateType || '',
-  day: props.data?.frequency?.day-0 || 0,
-})
-
-const dateTypeArr = [
-  { label: '每周', value: 'week' },
-  { label: '每月', value: 'month' },
-  { label: '每年', value: 'year' }
-]
-
-const majorData = ref([])
-const majorDataClone = ref([])
-const majorName = ref(props.data?.major || '')
-const handleSearchMajor = (e) => {
-  if (!e) return majorData.value = []
-  schoolMajorByName({ name: e }).then(res => {
-    const list = res?.data && res.data?.length ? res.data : []
-    setMajorData(list)
-    if (!list?.length) {
-      // majorName.value = ''
-      uni.showToast({ title: '未找到相关专业,请重新输入', icon: 'none', duration: 2000 })
-    }
-  })
-}
-function setMajorData (list) {
-  majorData.value = list.map(e => e.nameCn)
-  majorDataClone.value = list
-}
-// if (majorName.value) handleSearchMajor(majorName.value)
-
-async function getMajorById (id) {
-  if (!id) return
-  const { data } = await schoolMajorById({ id })
-  if (!data) return
-  majorName.value = data.nameCn
-  setMajorData([data])
-}
-if (props.data?.majorId) getMajorById(props.data.majorId)
-
-const form = ref()
-const getQuery = () => {
-  const obj = {
-    dept: formData.value.dept,
-    frequency: {
-      dateType: formData.value.dateType,
-      day: formData.value.day
-    },
-    major:  majorDataClone.value?.length ? majorName.value : '',
-    majorId:  majorDataClone.value?.length ? majorDataClone.value.find(e => e.nameCn === majorName.value)?.id : ''
-  }
-  return obj
-}
-
-defineExpose({
-  getQuery
-})
-
-</script>
-<style lang="scss" scoped>
-</style>

+ 0 - 234
components/positionItem/components/portrait.vue

@@ -1,234 +0,0 @@
-<template>
-  <uni-popup ref="popup" :is-mask-click="true" borderRadius="10px 10px 0 0" background-color="#fff" >
-      <view class="popup-content">
-        <view class="popup-content-close">
-          <view class="icon" @tap="handleClose">
-            <uni-icons
-              type="closeempty"
-              color="#999"
-              size="20"
-            />
-          </view>
-        </view>
-        <view class="popup-content-main">
-          <view class="box">
-            <!-- 已选中 -->
-            <view class="chose borderLine">
-              <view class="choseTitle">已选中关键字:</view>
-              <view class="tags">
-                <view
-                  v-for="tag in select"
-                  :key="tag"
-                  class="tag"
-                  style="color: orange; border: 2rpx solid orange;"
-                  @tap="handleCancelSelect(tag)"
-                >
-                  {{ tag }}
-                  <uni-icons type="clear" size="16" color="#ea8d03"></uni-icons>
-                </view>
-              </view>
-            </view>
-            <!-- 选择项 -->
-            <view v-if="showTagList && tagData?.length" class="list">
-              <uni-collapse v-model="collapseOpen">
-                <uni-collapse-item
-                  v-for="val in tagData" :key="val.id"
-                  :name="val.id"
-                  :title="val?.nameCn || '--'"
-                >
-                  <view v-if="val?.children?.length" class="tags">
-                    <view v-for="k in val.children" :key="k.id">
-                      <view v-if="select.includes(k.nameCn)" class="tag" style="color: grey; border: 2rpx solid grey;">
-                        <uni-icons type="plusempty" size="14" color="#00B760"></uni-icons>
-                        {{ k?.nameCn || '--' }}
-                      </view>
-                      <view v-else class="tag" style="color: #00B760; border: 2rpx solid #00B760;" @tap="handleSelect(k.nameCn)">
-                        <uni-icons type="plusempty" size="14" color="#00B760"></uni-icons>
-                        {{ k?.nameCn || '--' }}
-                      </view>
-                    </view>
-                  </view>
-                </uni-collapse-item>
-              </uni-collapse>
-            </view>
-            <view class="f-horizon-center">
-              <button type="primary" size="default" class="send-button"  @click="submit">提 交</button>
-            </view>
-          </view>
-        </view>
-      </view>
-    </uni-popup>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import { getTagTreeDataApi } from '@/api/user'
-const emit = defineEmits(['submit'])
-const props = defineProps({
-  tagSelected: {
-    type: Array,
-    default: () => []
-  }
-})
-
-const popup = ref()
-const handleClose = () => {
-  popup.value.close()
-}
-const handleOpen = () => {
-  popup.value.open('bottom')
-}
-
-// 选择
-const handleSelect = (nameCn) => {
-  const result = select.value.includes(nameCn)
-  if (!result) return select.value.push(nameCn)
-  else select.value = select.value.filter(e => e !== nameCn)
-}
-
-// 删除
-const handleCancelSelect = (nameCn) => {
-  select.value = select.value.filter(e => e !== nameCn)
-}
-
-const select = ref(props.tagSelected || [])
-const tagData = ref([])
-const collapseOpen = ref([])
-const showTagList = ref(false)
-// 获取标签字典数据
-const getTagList = async () => {
-  showTagList.value = false
-  const res = await getTagTreeDataApi({ type: 2 })
-  const data = res?.data?.length ? res.data : []
-  tagData.value = data
-  showTagList.value = true
-}
-getTagList()
-
-// 提交
-const submit = () => {
-  emit('submit', select.value)
-  handleClose()
-}
-
-defineExpose({
-  handleOpen
-})
-</script>
-
-<style lang="scss" scoped>
-$px: 30rpx;
-.borderLine {
-  border-bottom: 2rpx solid #f5f5f5;
-}
-.box {
-  padding: 20rpx $px;
-  .chose {
-    margin-bottom: $px;
-    .choseTitle {
-      margin-bottom: $px;
-    }
-  }
-  .tags {
-    padding: $px 0;
-    display: flex;
-    flex-wrap: wrap;
-    .tag {
-      margin: 0 15rpx 12rpx 0;
-      border: 2rpx 15rpx #00B760;
-      color: #00B760;
-      white-space: nowrap;
-      padding: 4rpx 10rpx;
-      border-radius: 10rpx;
-      font-size: 24rpx;
-    }
-  }
-}
-
-.popup-content {
-  z-index: 999;
-  max-height: 500px;
-  display: flex;
-  flex-direction: column;
-  &-close {
-    display: flex;
-    padding: 10px;
-    justify-content: flex-end;
-    .icon {
-      width: 30px;
-      height: 30px;
-      background: #ccc;
-      border-radius: 30px;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-    }
-  }
-  &-main {
-    flex: 1;
-    height: 0;
-    overflow-y: auto;
-    &-count {
-      margin-bottom: 20px;
-      text-align: center;
-      .title {
-        font-size: 28rpx;
-        color: #666
-      }
-      .pay {
-        font-size: 52rpx;
-        color: #000;
-        font-weight: 600;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        padding: 10px 0;
-      }
-    }
-    &-type {
-      width: 100%;
-      padding: 0 20px;
-      box-sizing: border-box;
-      .card {
-        border-radius: 10px;
-        margin: 0 auto;
-        background: #FFF;
-        padding: 10px;
-        &-label {
-          padding: 15px 0;
-          box-sizing: border-box;
-          display: flex;
-          justify-content: space-between;
-          border-bottom: 1px solid #eee;
-          &:last-of-type {
-            border-bottom: none;
-          }
-          .name {
-            display: flex;
-            align-items: center;
-            color: #333;
-          }
-        }
-      }
-    }
-  }
-  &-btn {
-    height: 70px;
-    width: 100%;
-    margin-top: 10px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    &-s {
-      height: 40px;
-      width: 75%;
-      line-height: 40px;
-      color: #FFF;
-      // color: #724d2b;
-      background: #00B760;
-      // background: linear-gradient(121deg,#fde2c2 29.02%,#c19164 104.03%);
-      border-radius: 90px;
-    }
-  }
-}
-</style>

+ 0 - 246
components/positionItem/components/requirement.vue

@@ -1,246 +0,0 @@
-<!--  -->
-<template>
-	<view class="f-straight wrapper">
-		<uni-forms ref="form" :modelValue="formData" :rules="rules" validateTrigger="bind" label-width="90px" label-align="right">
-			<uni-forms-item label="招聘类型" name="type" required>
-				<uni-data-picker popup-title="请选择招聘类型" v-model="formData.type" :localdata="jobType" :clear-icon="false" :map="{ text: 'key', value: 'value'}"></uni-data-picker>
-			</uni-forms-item>
-			<uni-forms-item label="学历要求" name="eduType" required>
-				<uni-data-picker popup-title="请选择学历要求" v-model="formData.eduType" :localdata="dictObj?.edu_extend || []" :clear-icon="false" :map="{ text: 'label', value: 'value'}"></uni-data-picker>
-			</uni-forms-item>
-			<uni-forms-item label="工作经验" name="expType" required>
-				<uni-data-picker popup-title="请选择工作经验" v-model="formData.expType" :localdata="dictObj?.exp_extend || []" :clear-icon="false" :map="{ text: 'label', value: 'value'}"></uni-data-picker>
-			</uni-forms-item>
-      <uni-forms-item label="最低薪资" name="payFrom" :required="salary?.length === 0" label-width="90px">
-				<view class="d-flex">
-          <uni-number-box v-model="formData.payFrom" :disabled="salary?.length > 0" :min="1" :max="999999999" :step="salaryStep" :width="100" @change="payChange"></uni-number-box>
-          <uni-data-checkbox v-model="salary" multiple :localdata="[{ text: '薪资面议', value: 1 }]" selectedColor="#00B760" class="ss-m-l-20" @change="salaryCheckboxChange"></uni-data-checkbox>
-        </view>
-			</uni-forms-item>
-      <uni-forms-item label="最高薪资" name="payTo" :required="salary?.length === 0" label-width="90px">
-        <uni-number-box v-model="formData.payTo" :disabled="salary?.length > 0" :min="payToMin" :max="999999999" :step="salaryStep" :width="100"></uni-number-box>
-			</uni-forms-item>
-			<uni-forms-item v-if="!salary?.length" label="计薪时段" name="payUnit" required>
-				<uni-data-picker popup-title="请选择计薪时段" v-model="formData.payUnit" placeholder="请选择" :localdata="dictObj?.payUnit || []" :clear-icon="false" :map="{ text: 'label', value: 'value'}"></uni-data-picker>
-			</uni-forms-item>
-      <uni-forms-item label="工作城市" name="areaId" required label-width="90px">
-				<uni-data-picker popup-title="请选择工作城市" v-model="formData.areaId" :localdata="dictObj?.areaTreeData_extend || []" :clear-icon="false" :map="{ text: 'name', value: 'id'}"></uni-data-picker>
-			</uni-forms-item>
-			<uni-forms-item required label="详情地址" name="address">
-        <uni-easyinput v-model="formData.address" placeholder="请填写详细地址"></uni-easyinput>
-			</uni-forms-item>
-			<uni-forms-item label="职位关键字" name="tagList">
-        <view class="tagsBox" @tap="portraitOpen">
-          <view class="tags" v-if="tagList?.length">
-            <view
-              v-for="tag in tagList"
-              :key="tag"
-              class="tag"
-            >
-              {{ tag }}
-            </view>
-          </view>
-          <uni-icons
-            type="icon-Edit"
-            color="#00B760"
-            class="ss-m-t-20"
-            custom-prefix="iconfont"
-            size="18"
-          ></uni-icons>
-        </view>
-			</uni-forms-item>
-		</uni-forms>
-    <portrait ref="portraitRef" :tagSelected="tagList" @submit="portraitSubmit"></portrait>
-	</view>
-</template>
-<script setup>
-import { ref, unref } from 'vue'
-import { dictObj } from '@/utils/position.js'
-import { getEnterprisePubJobTypePermission } from '@/api/new/position'
-import portrait from './portrait.vue'
-// const emit = defineEmits(['requireTypeChange'])
-const props = defineProps({
-  data: {
-    type: Object,
-    default: () => {}
-  }
-})
-
-const formData = ref({
-  type: props.data?.type || '',
-  eduType: props.data?.eduType ? props.data?.eduType : props.data?.eduType === null ? -1 : '',
-  expType: props.data?.expType ? props.data?.expType : props.data?.expType === null ? -1 : '',
-  payFrom: props.data?.payFrom || '',
-  payTo: props.data?.payTo || '',
-  payUnit: props.data?.payUnit || '',
-  areaId: props.data?.areaId ? props.data?.areaId : props.data?.areaId === null ? -1 : '',
-  address: props.data?.address || '',
-})
-const tagList = ref(props.data?.tagList?.length ? props.data.tagList : [])
-
-// const salaryDisabled = computed(() => {
-//   return Boolean(salary?.value.length)
-// })
-
-const salaryCheckboxChange = (e) => {
-  const bool = e.detail.value.length ? e.detail.value[0] : ''
-  salary.value = bool ? [1] : []
-  formData.value.payFrom = null
-  formData.value.payTo = null
-  formData.value.payUnit = null
-}
-
-const rules = {
-	type:{
-		rules: [{required: true, errorMessage: '请选择招聘类型' }]
-	},
-	eduType:{
-		rules: [{required: true, errorMessage: '请选择学历要求' }]
-	},
-	expType:{
-		rules: [{required: true, errorMessage: '请选择工作经验' }]
-	},
-	areaId:{
-		rules: [{required: true, errorMessage: '请选择工作城市' }]
-	},
-	address:{
-		rules: [{required: true, errorMessage: '请填写详细地址' }]
-	},
-  // 薪资
-	payFrom: {
-		rules: [
-      // { required: true, errorMessage: '请填写最低薪资' },
-      {
-        validateFunction: function (rule, value, data, callback) {
-          if (value < 1) {
-            callback('数额不得小于1')
-          }
-          return true
-        }
-      },
-      {
-        validateFunction: function (rule, value, data, callback) {
-          if (!formData.value?.payTo || (Number(value) < formData.value.payTo ? Number(formData.value.payTo) : 0)) {
-            return true
-          } else {
-            callback('应低于最高薪资')
-          }
-        }
-      }
-    ]
-	},
-	payTo: {
-		rules: [
-      // { required: true, errorMessage: '请填写最高薪资' },
-      {
-        validateFunction: function (rule, value, data, callback) {
-          if (value < 1) {
-            callback('数额不得小于1')
-          }
-          return true
-        }
-      },
-      {
-        validateFunction: function (rule, value, data, callback) {
-          if (!formData.value?.payFrom || (Number(value) > formData.value?.payFrom ? Number(formData.value?.payFrom) : 0)) {
-            return true
-          } else {
-            callback('应高于最低薪资')
-          }
-        }
-      }
-    ]
-	},
-	payUnit: {
-		rules: [{required: true, errorMessage: '请选择计薪时段' }]
-	}
-}
-// const salaryRules = {}
-
-const jobType = ref([])
-const getJobTypeList = async () => {
-  const res = await getEnterprisePubJobTypePermission()
-  jobType.value = res?.data?.length ? res.data : []
-}
-getJobTypeList()
-
-// 薪资面议
-const salaryStep = 1000
-const payToMin = ref(0)
-const payChange = (val) => {
-  payToMin.value = val
-  if (val > formData.value.payTo) formData.value.payTo = val + salaryStep
-}
-
-const portraitRef = ref()
-const portraitOpen = () => {
-  portraitRef.value?.handleOpen()
-}
-const portraitSubmit = (arr) => {
-  tagList.value = arr?.length ? arr : []
-}
-
-// const typeChange = (e) => {
-//   const bool = Boolean(e?.detail?.value?.length ? e.detail.value[0]?.text === '实习' : false)
-//   emit('requireTypeChange', bool)
-// }
-
-const form = ref()
-// const salary = ref([])
-const salary = ref((props.data?.payFrom === null &&props.data?.payTo === null) ? [1] : [])
-const getQuery = async () => {
-  const valid = await unref(form).validate()
-  if (!valid) return
-  const obj = {
-    hirePrice: 0,
-    hire: false,
-    salary: Boolean(salary.value?.length),
-    tagList: tagList.value,
-    ...formData.value
-  }
-  
-  obj && Object.keys(obj).length && Object.keys(obj).forEach(key => {
-    if (['areaId', 'eduType', 'expType'].includes(key) && obj[key] === -1) obj[key] = null 
-    if (obj.salary && ['payFrom', 'payTo', 'payUnit'].includes(key)) obj[key] = null 
-  })
-
-  return obj
-}
-
-defineExpose({
-  getQuery
-})
-
-</script>
-<style lang="scss" scoped>
-$px: 30rpx;
-.positionTemplate {
-  display: flex;
- .picker {
-  flex: 1;
-  margin-right: 5px;
- }
- .btn {
-  width: 90px;
-  line-height: 34px;
- }
-}
-.tagsBox {
-  display: flex;
-  flex-wrap: wrap;
-  .tags {
-    padding-top: 10px;
-    display: flex;
-    flex-wrap: wrap;
-    .tag {
-      margin: 0 10rpx 10rpx 0;
-      border: 2rpx solid #00B760;
-      color: #00B760;
-      white-space: nowrap;
-      padding: 4rpx 10rpx;
-      border-radius: 10rpx;
-      font-size: 24rpx;
-    }
-  }
-}
-</style>

+ 0 - 226
components/positionItem/components/tableItems.vue

@@ -1,226 +0,0 @@
-<template>
-  <view v-if="list?.length" class="ss-p-b-30 ss-p-t-20">
-    <view v-for="(item, index) in list" :key="index" class="mList">
-      <view v-if="item?.hrName" class="d-flex align-center item-top">
-        <view class="avatarBox">
-          <image class="enterAvatar" :src="getUserAvatar(item.hrHeadImg)"></image>
-        </view>
-        <view class="ss-m-l-20 label-text">{{ item?.hrName }}</view>
-      </view>
-      <!-- 职位信息 -->
-      <view class="list-shape" style="border-radius: 12px;">
-        <!-- 职位 -->
-        <view class="titleBox my-5">
-          <view style="display: flex;align-items: center;">
-            <image v-if="item.jobFairIds?.length" src="/static/svg/jobFair.svg" class=" ss-m-r-10" style="width: 20px; height: 20px;"></image>
-            <rich-text v-if="item.name?.indexOf('style') !== -1" class="job-name" :nodes="item.name"></rich-text>
-            <view v-else class="job-name">{{ formatName(item.name) }}</view>
-          </view>
-          <image v-if="item.top && tab === 1" src="/static/svg/topUp.svg" class="TopUpSvg"></image>
-        </view>
-        <!-- 职位类型 -->
-        <view class="font-size-13 ellipsis ss-m-5" style="color: #808080;">
-          <span>{{item.positionName }}</span>
-        </view>
-        <!-- 薪酬、工作地、学历、工作经验 -->
-        <view class="d-flex align-center justify-space-between">
-          <view class="font-size-13 ellipsis" style="flex: 1;">
-            <span class="tag-gap" style="color: #808080;">
-              <span>{{item.area?.str ?? '全国' }}</span>
-              <span class="divider-mx" v-if="item.eduName">|</span>
-              <span>{{item.eduName }}</span>
-              <span class="divider-mx" v-if="item.expName">|</span>
-              <span>{{item.expName }}</span>
-              <span class="divider-mx">|</span>
-              <span>{{!item.payFrom && !item.payTo ? '面议' : `${item.payFrom}-${item.payTo}${item.payName ? '/' + item.payName : ''}` }}</span>
-            </span>
-          </view>
-        </view>
-        <view class="d-flex font-size-13 color-666 ss-m-t-10">
-          <!-- <view class="ss-m-t-10 ss-m-r-15">到期时间:{{ item.expireTime ? timesTampChange(item.expireTime, 'Y-M-D') : '长期有效' }}</view> -->
-          <view class="ss-m-t-10">刷新时间:{{ item.refreshTime ? timesTampChange(item.refreshTime, 'Y-M-D h:m') : '暂无' }}</view>
-        </view>
-        <view class="sub-li-bottom ss-m-t-20">
-          <view  class="sub-li-bottom-item color-primary" style="width: 100%;" @tap.stop="handleDetail(item)">查看详情</view>
-        </view>
-      </view>
-    </view>
-  </view>
-</template>
-<script setup>
-import { timesTampChange } from '@/utils/date'
-import { formatName } from '@/utils/getText'
-import { getUserAvatar } from '@/utils/avatar'
-
-const props = defineProps({
-  list: { type: Array, default: () => [] },
-})
-
-// 职位详情
-const handleDetail = (item) => {
-  if (!item.id) return
-  let url = `/pagesB/positionDetail/index?jobId=${item.id}&isEdit=${item.edit}`
-  uni.navigateTo({ url })
-}
-</script>
-
-<style scoped lang="scss">
-.avatarBox {
-  max-width: 60rpx;
-  max-height: 60rpx;
-}
-.item-top {
-  padding: 20rpx 30rpx;
-  background: linear-gradient(90deg,#f5fcfc,#fcfbfa);
-  border-radius: 12px 12px 0 0;
-  font-size: 28rpx;
-  color: #0E100F;
-  .label-text {
-	  max-width: 100%;
-	  text-overflow: ellipsis;
-	  white-space: nowrap;
-	  overflow: hidden;
-  }
-}
-
-.date-time{
-  color:#d9d0d2;
-  float: right;
-}
-
-.divided-line {
-  width: 100%;
-  height: 1px;
-  background-color: #f0f2f7;
-  margin: 20px 0;
-
-}
-.enterAvatar{
-	width: 60rpx;
-	height: 60rpx;
-	margin: auto;
-  border-radius: 50%;
-}
-
-.job-name {
-  font-size: 16px;
-  font-weight: 700;
-  color: #0E100F;
-  max-width: 80vw;
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-}
-
-
-.salary-text {
-	float: right;
-	color: #00B760;
-  font-weight: 700;
-}
-.list-shape {
-	padding: 10px 30rpx 10px;
-  border-radius: 12px 12px 0 0;
-  .titleBox {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-  }
-}
-.tag-gap{
-	margin: 10rpx 10rpx 10rpx 0;
-}
-.tag-gap1{
-  margin-bottom: 20px;
-}
-.divider-mx{
-	margin: 0 10rpx;
-}
-.divider {
-	color:#e4d4d2;
-}
-
-//公司名称
-.cer-end{
-  position: absolute;
-  top: 85%;
-  right: 16%;
-}
-.cer-text{
-  text-decoration: underline;
-  margin: 0 5rpx;
-}
-//一行展示不全...
-.dis{
-	display: flex;
-	align-items: center;
-}
-.mList {
-  margin-bottom: 20rpx;
-  margin-left: 20rpx;
-  margin-right: 20rpx;
-  position: relative;
-  box-shadow: 1px 2px 12px rgba(0, 0, 0, 0.17);
-  border-radius: 20rpx;
-  background-color: #fbfbfb;
-}
-/* 列表触底暂无更多 */
-.mt { margin-top: 15rpx; }
-.mb { margin-bottom: 10rpx; }
-.ml { margin-left: 20rpx; }
-.mr { margin-right: 20rpx; }
-.mr-10{ margin-right: 10rpx; }
-.my-5{ margin: 5px 0; }
-.disable {
-  position: relative;
-  overflow: hidden;
-  &::after {
-    content: '已失效';
-    position: absolute;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    font-size: 1.2em;
-    font-weight: bold;
-    color: #fc796f;
-    top: 0;
-    border-radius: 12px;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    background-color: rgba(255, 255, 255, 0.75);
-  }
-}
-.resumeCount {
-  color: #00B760;
-  font-size: 12px;
-  margin: 0 10px;
-}
-
-.sub-li-bottom {
-  display: flex;
-  justify-content: flex-end;
-  margin-top: 10px;
-  font-size: 13px;
-  color: #666;
-	&-item {
-		width: 25%;
-		height: 35px;
-		line-height: 35px;
-		text-align: center;
-		margin-right: 15px;
-		background-color: #f7f8fa;
-		border-radius: 4px;
-		&:last-child {
-			margin-right: 0;
-		}
-	}
-}
-.TopUpSvg {
-  width: 45px;
-  height: 45px;
-  position: absolute;
-  top: -3px;
-  right: -4px;
-}
-</style>

+ 0 - 218
components/positionItem/index.vue

@@ -1,218 +0,0 @@
-<template>
-  <view v-if="show" class="ss-m-x-20 ss-p-b-100">
-    <uni-section class="ss-m-y-20" title="职位基本信息">
-      <template v-slot:decoration>
-        <view class="decoration decoration1">1</view>
-      </template>
-      <!-- 基本信息 -->
-      <baseInfo ref="baseInfoRef" :data="itemData"></baseInfo>
-    </uni-section>
-    <uni-section class="ss-m-y-20" title="岗位要求">
-      <template v-slot:decoration>
-        <view class="decoration decoration2">2</view>
-      </template>
-      <!-- 岗位要求 -->
-      <requirement ref="requirementRef" :data="itemData"></requirement>
-    </uni-section>
-    <!-- <template v-if="isStudent">
-      <uni-section class="ss-m-y-20" title="其他">
-        <template v-slot:decoration>
-          <view class="decoration decoration3">3</view>
-        </template>
-        <extendInfo ref="extendRef" :data="extendData"></extendInfo>
-      </uni-section>
-    </template> -->
-    <view class="f-horizon-center">
-      <button type="primary" size="default" class="send-button" @click="getSubmitParams">提 交</button>
-    </view>
-    <!-- 支付 -->
-    <payPopup ref="payRef" :tabBar="false" @paySuccess="paySuccess" @close="payClose"></payPopup>
-  </view>
-</template>
-
-<script setup>
-import baseInfo from './components/baseInfo.vue'
-import requirement from './components/requirement.vue'
-// import extendInfo from './components/extend.vue'
-import { ref, nextTick } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import payPopup from '@/components/payPopup'
-import { dealDictObjData } from '@/utils/position'
-import {
-  saveJobAdvertised,
-  // saveJobAdvertisedExtend,
-  getJobDetails,
-  // getJobAdvertisedExtend,
-} from '@/api/new/position'
-const props = defineProps({
-  jobId: String,
-  fairId: String,
-  isClone: { type: Boolean, default: false }
-})
-
-const jobId = ref('')
-onLoad((options) => {
-  jobId.value = options?.jobId || props.jobId || ''
-  if (jobId.value) getPositionDetail(jobId.value)
-  else {
-    show.value = true
-  }
-})
-
-// 获取编辑的职位详情
-const show = ref(false)
-const itemData = ref({})
-const getPositionDetail = async (id) => {
-  try {
-    uni.showLoading({ title: '加载中...', mask: true })
-    const res = await getJobDetails({ id })
-    if (!res?.data || !Object.keys(res.data).length) return
-    itemData.value = {...res.data, ...dealDictObjData({}, res.data)}
-    // itemData.value.name = new Date().getTime().toString() + '测试小程序发布职位'
-    // if (itemData.value?.type === '3') {
-    //   await getPositionExtendDetail(id)
-    // }
-    show.value = true
-  } finally {
-    uni.hideLoading()
-  }
-}
-// // 测试数据
-// setTimeout(async() => {
-//   show.value = false
-//   await getPositionDetail('1904786675108691969')
-// }, 2000)
-
-// 获取实习扩展信息
-// const extendData = ref({})
-// const getPositionExtendDetail = async (id) => {
-//   try {
-//     const res = await getJobAdvertisedExtend(id)
-//     extendData.value = res?.data || {}
-//     isStudent.value = true
-//   } catch (error) {
-//   }
-// }
-
-const baseInfoRef = ref(null)
-const requirementRef = ref(null)
-// const extendRef = ref(null)
-let submitParams = null
-const getSubmitParams = async() => {
-  const baseInfo = await baseInfoRef.value.getQuery()
-  const requirement = await requirementRef.value.getQuery()
-  if (!baseInfo || !requirement) return
-
-  // if (cleanedHtml(baseInfo.content)?.length > 5000) return uni.showToast({ title: '岗位职责字数超出限制', icon: 'none', duration: 2000 })
-  // if (cleanedHtml(baseInfo.requirement)?.length > 5000) return uni.showToast({ title: '岗位要求字数超出限制', icon: 'none', duration: 2000 })
-  
-  submitParams = {
-    ...baseInfo,
-    ...requirement,
-    fair: props.fairId ? true : false, // fair:是否为招聘会职位编辑-必填
-    currency_type: 0, // currency_type: 写死0(人民币)
-    source: props.fairId ? '2' : '0', // source: 职位来源(0职位管理|1众聘职位|2招聘会)
-  }
-  if (props.fairId) submitParams.bizId = props.fairId // 招聘会职位添加招聘会id
-  
-  if (!submitParams.salary) {
-    if (!submitParams.payFrom) return uni.showToast({ title: '请填写最低薪资', icon: 'none', duration: 2000 })
-    if (!submitParams.payTo) return uni.showToast({ title: '请填写最高薪资', icon: 'none', duration: 2000 })
-  }
-  
-  if (jobId.value && !props.isClone) submitParams.id = jobId.value  // 有id则为编辑, 职位克隆不需要id
-  saveEmit()
-}
-// 
-const price = 39900 // 39900 职位价格,传递单位:分
-// const isStudent = ref(false)
-let _jobId = ''
-const saveEmit = async (retry) => {
-  try {
-    uni.showLoading({ title: '操作中...', mask: true })
-    const res = await saveJobAdvertised(submitParams)
-    _jobId = res?.data || res || ''
-    // if (isStudent.value) handleSaveExtend() // 保存扩展信息
-    // status:99为待支付职位,弹窗支付
-    if (submitParams?.status && submitParams?.status === '99') {
-      uni.showToast({ title: '当前可发布职位额度不足,请支付', icon: 'none', duration: 2000 })
-      nextTick(() => {
-        // 金额*100,页面展示/100
-        payRef.value && payRef.value.handleOpen({ spuId: _jobId||'', spuName: submitParams?.name||'', price, type: 1 })
-      })
-      return
-    }
-    if (!props.fairId) uni.switchTab({ url: '/pages/index/position' })
-    else {
-      uni.reLaunch({
-        url: `/pagesB/jobFair/details?id=${props.fairId}`
-      })
-    }
-    // const title = itemData.value?.status === '99' '编辑成功,请前往支付' : jobId.value ? '编辑成功' : '发布成功'
-    setTimeout(() => { uni.showToast({ title: jobId.value ? '编辑成功' : '发布成功', icon: 'success' }) }, 1000)
-
-  } catch (error) {
-    console.log('error:', error)
-    // 可发布职位额度不足时,将status设为99重新提交
-    if (error?.msg === '企业额度已超过') {
-      submitParams.status = '99'
-      setTimeout(() => {
-        if (!retry) saveEmit(true) // true:重新提交避免死循环
-      }, 1000)
-    }
-    // else if (error?.msg === '招聘会时间已过,暂停招聘') {
-    //   uni.showToast({ title: error.msg, icon: 'none', duration: 2000 })
-    // }
-  } finally {
-    uni.hideLoading()
-  }
-}
-
-const payRef = ref(null)
-const paySuccess = () => {
-  uni.switchTab({ url: '/pages/index/position' })
-  setTimeout(() => { uni.showToast({ title: '发布成功', icon: 'success', duration: 2000 }) }, 1000)
-}
-const payClose = () => {
-  setTimeout(() => { uni.showToast({ title: '您已取消支付,请前往待发布查看!', icon: 'none', duration: 3000 }) }, 500)
-  uni.switchTab({ url: '/pages/index/position' }) // 不支持传参
-}
-
-// 保存扩展信息
-// const handleSaveExtend = async () => {
-//   if (!_jobId) return
-//   try {
-//     const extend = await extendRef.value && extendRef.value.getQuery() || null
-//     if (!extend) return
-//     await saveJobAdvertisedExtend({ ...extend, jobId: _jobId })
-//   } catch (error) {
-//     console.error('保存扩展信息失败', error)
-//   }
-// }
-
-</script>
-
-<style scoped lang="scss">
-.decoration {
-  color: #fff;
-  border-radius: 50%;
-  width: 15px;
-  height: 15px;
-  line-height: 15px;
-  font-size: 10px;
-  text-align: center;
-  margin-right: 4px;
-}
-
-.decoration1 {
-  background-color: #00b760;
-}
-
-.decoration2 {
-  background-color: #7a87c9;
-}
-
-.decoration3 {
-  background-color: #1caaf2;
-}
-</style>

+ 28 - 0
components/uni-calendar/changelog.md

@@ -0,0 +1,28 @@
+## 1.4.11(2024-01-10)
+- 修复 回到今天时,月份显示不一致问题
+## 1.4.10(2023-04-10)
+- 修复 某些情况 monthSwitch 未触发的Bug
+## 1.4.9(2023-02-02)
+- 修复 某些情况切换月份错误的Bug
+## 1.4.8(2023-01-30)
+- 修复 某些情况切换月份错误的Bug [详情](https://ask.dcloud.net.cn/question/161964)
+## 1.4.7(2022-09-16)
+- 优化 支持使用 uni-scss 控制主题色
+## 1.4.6(2022-09-08)
+- 修复 表头年月切换,导致改变当前日期为选择月1号,且未触发change事件的Bug
+## 1.4.5(2022-02-25)
+- 修复 条件编译 nvue 不支持的 css 样式的Bug
+## 1.4.4(2022-02-25)
+- 修复 条件编译 nvue 不支持的 css 样式的Bug
+## 1.4.3(2021-09-22)
+- 修复 startDate、 endDate 属性失效的Bug
+## 1.4.2(2021-08-24)
+- 新增 支持国际化
+## 1.4.1(2021-08-05)
+- 修复 弹出层被 tabbar 遮盖的Bug
+## 1.4.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.3.16(2021-05-12)
+- 新增 组件示例地址
+## 1.3.15(2021-02-04)
+- 调整为uni_modules目录规范

+ 546 - 0
components/uni-calendar/components/uni-calendar/calendar.js

@@ -0,0 +1,546 @@
+/**
+* @1900-2100区间内的公历、农历互转
+* @charset UTF-8
+* @github  https://github.com/jjonline/calendar.js
+* @Author  Jea杨(JJonline@JJonline.Cn)
+* @Time    2014-7-21
+* @Time    2016-8-13 Fixed 2033hex、Attribution Annals
+* @Time    2016-9-25 Fixed lunar LeapMonth Param Bug
+* @Time    2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year
+* @Version 1.0.3
+* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
+* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
+*/
+/* eslint-disable */
+var calendar = {
+
+  /**
+      * 农历1900-2100的润大小信息表
+      * @Array Of Property
+      * @return Hex
+      */
+  lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909
+    0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919
+    0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929
+    0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939
+    0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949
+    0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959
+    0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969
+    0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979
+    0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989
+    0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999
+    0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009
+    0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019
+    0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029
+    0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039
+    0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049
+    /** Add By JJonline@JJonline.Cn**/
+    0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059
+    0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069
+    0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079
+    0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089
+    0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099
+    0x0d520], // 2100
+
+  /**
+      * 公历每个月份的天数普通表
+      * @Array Of Property
+      * @return Number
+      */
+  solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
+
+  /**
+      * 天干地支之天干速查表
+      * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
+      * @return Cn string
+      */
+  Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'],
+
+  /**
+      * 天干地支之地支速查表
+      * @Array Of Property
+      * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
+      * @return Cn string
+      */
+  Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'],
+
+  /**
+      * 天干地支之地支速查表<=>生肖
+      * @Array Of Property
+      * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
+      * @return Cn string
+      */
+  Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'],
+
+  /**
+      * 24节气速查表
+      * @Array Of Property
+      * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
+      * @return Cn string
+      */
+  solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'],
+
+  /**
+      * 1900-2100各年的24节气日期速查表
+      * @Array Of Property
+      * @return 0x string For splice
+      */
+  sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f',
+    '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+    '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f',
+    'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f',
+    '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa',
+    '97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2',
+    '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f',
+    '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+    '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f',
+    '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+    '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f',
+    '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
+    '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
+    '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722',
+    '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+    '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+    '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
+    '9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722',
+    '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
+    '97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
+    '9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
+    '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+    '97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
+    '9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
+    '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721',
+    '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2',
+    '977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
+    '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
+    '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
+    '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
+    '977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
+    '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721',
+    '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5',
+    '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722',
+    '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35',
+    '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
+    '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721',
+    '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd',
+    '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35',
+    '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
+    '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721',
+    '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5',
+    '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35',
+    '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
+    '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
+    '7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35',
+    '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'],
+
+  /**
+      * 数字转中文速查表
+      * @Array Of Property
+      * @trans ['日','一','二','三','四','五','六','七','八','九','十']
+      * @return Cn string
+      */
+  nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'],
+
+  /**
+      * 日期转农历称呼速查表
+      * @Array Of Property
+      * @trans ['初','十','廿','卅']
+      * @return Cn string
+      */
+  nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'],
+
+  /**
+      * 月份转农历称呼速查表
+      * @Array Of Property
+      * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
+      * @return Cn string
+      */
+  nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'],
+
+  /**
+      * 返回农历y年一整年的总天数
+      * @param lunar Year
+      * @return Number
+      * @eg:var count = calendar.lYearDays(1987) ;//count=387
+      */
+  lYearDays: function (y) {
+    var i; var sum = 348
+    for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 }
+    return (sum + this.leapDays(y))
+  },
+
+  /**
+      * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0
+      * @param lunar Year
+      * @return Number (0-12)
+      * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
+      */
+  leapMonth: function (y) { // 闰字编码 \u95f0
+    return (this.lunarInfo[y - 1900] & 0xf)
+  },
+
+  /**
+      * 返回农历y年闰月的天数 若该年没有闰月则返回0
+      * @param lunar Year
+      * @return Number (0、29、30)
+      * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
+      */
+  leapDays: function (y) {
+    if (this.leapMonth(y)) {
+      return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29)
+    }
+    return (0)
+  },
+
+  /**
+      * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法
+      * @param lunar Year
+      * @return Number (-1、29、30)
+      * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
+      */
+  monthDays: function (y, m) {
+    if (m > 12 || m < 1) { return -1 }// 月份参数从1至12,参数错误返回-1
+    return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29)
+  },
+
+  /**
+      * 返回公历(!)y年m月的天数
+      * @param solar Year
+      * @return Number (-1、28、29、30、31)
+      * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
+      */
+  solarDays: function (y, m) {
+    if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
+    var ms = m - 1
+    if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29
+      return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28)
+    } else {
+      return (this.solarMonth[ms])
+    }
+  },
+
+  /**
+     * 农历年份转换为干支纪年
+     * @param  lYear 农历年的年份数
+     * @return Cn string
+     */
+  toGanZhiYear: function (lYear) {
+    var ganKey = (lYear - 3) % 10
+    var zhiKey = (lYear - 3) % 12
+    if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干
+    if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支
+    return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1]
+  },
+
+  /**
+     * 公历月、日判断所属星座
+     * @param  cMonth [description]
+     * @param  cDay [description]
+     * @return Cn string
+     */
+  toAstro: function (cMonth, cDay) {
+    var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf'
+    var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22]
+    return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座
+  },
+
+  /**
+      * 传入offset偏移量返回干支
+      * @param offset 相对甲子的偏移量
+      * @return Cn string
+      */
+  toGanZhi: function (offset) {
+    return this.Gan[offset % 10] + this.Zhi[offset % 12]
+  },
+
+  /**
+      * 传入公历(!)y年获得该年第n个节气的公历日期
+      * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起
+      * @return day Number
+      * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
+      */
+  getTerm: function (y, n) {
+    if (y < 1900 || y > 2100) { return -1 }
+    if (n < 1 || n > 24) { return -1 }
+    var _table = this.sTermInfo[y - 1900]
+    var _info = [
+      parseInt('0x' + _table.substr(0, 5)).toString(),
+      parseInt('0x' + _table.substr(5, 5)).toString(),
+      parseInt('0x' + _table.substr(10, 5)).toString(),
+      parseInt('0x' + _table.substr(15, 5)).toString(),
+      parseInt('0x' + _table.substr(20, 5)).toString(),
+      parseInt('0x' + _table.substr(25, 5)).toString()
+    ]
+    var _calday = [
+      _info[0].substr(0, 1),
+      _info[0].substr(1, 2),
+      _info[0].substr(3, 1),
+      _info[0].substr(4, 2),
+
+      _info[1].substr(0, 1),
+      _info[1].substr(1, 2),
+      _info[1].substr(3, 1),
+      _info[1].substr(4, 2),
+
+      _info[2].substr(0, 1),
+      _info[2].substr(1, 2),
+      _info[2].substr(3, 1),
+      _info[2].substr(4, 2),
+
+      _info[3].substr(0, 1),
+      _info[3].substr(1, 2),
+      _info[3].substr(3, 1),
+      _info[3].substr(4, 2),
+
+      _info[4].substr(0, 1),
+      _info[4].substr(1, 2),
+      _info[4].substr(3, 1),
+      _info[4].substr(4, 2),
+
+      _info[5].substr(0, 1),
+      _info[5].substr(1, 2),
+      _info[5].substr(3, 1),
+      _info[5].substr(4, 2)
+    ]
+    return parseInt(_calday[n - 1])
+  },
+
+  /**
+      * 传入农历数字月份返回汉语通俗表示法
+      * @param lunar month
+      * @return Cn string
+      * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'
+      */
+  toChinaMonth: function (m) { // 月 => \u6708
+    if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
+    var s = this.nStr3[m - 1]
+    s += '\u6708'// 加上月字
+    return s
+  },
+
+  /**
+      * 传入农历日期数字返回汉字表示法
+      * @param lunar day
+      * @return Cn string
+      * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'
+      */
+  toChinaDay: function (d) { // 日 => \u65e5
+    var s
+    switch (d) {
+      case 10:
+        s = '\u521d\u5341'; break
+      case 20:
+        s = '\u4e8c\u5341'; break
+        break
+      case 30:
+        s = '\u4e09\u5341'; break
+        break
+      default :
+        s = this.nStr2[Math.floor(d / 10)]
+        s += this.nStr1[d % 10]
+    }
+    return (s)
+  },
+
+  /**
+      * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春”
+      * @param y year
+      * @return Cn string
+      * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'
+      */
+  getAnimal: function (y) {
+    return this.Animals[(y - 4) % 12]
+  },
+
+  /**
+      * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON
+      * @param y  solar year
+      * @param m  solar month
+      * @param d  solar day
+      * @return JSON object
+      * @eg:console.log(calendar.solar2lunar(1987,11,01));
+      */
+  solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31
+    // 年份限定、上限
+    if (y < 1900 || y > 2100) {
+      return -1// undefined转换为数字变为NaN
+    }
+    // 公历传参最下限
+    if (y == 1900 && m == 1 && d < 31) {
+      return -1
+    }
+    // 未传参  获得当天
+    if (!y) {
+      var objDate = new Date()
+    } else {
+      var objDate = new Date(y, parseInt(m) - 1, d)
+    }
+    var i; var leap = 0; var temp = 0
+    // 修正ymd参数
+    var y = objDate.getFullYear()
+    var m = objDate.getMonth() + 1
+    var d = objDate.getDate()
+    var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000
+    for (i = 1900; i < 2101 && offset > 0; i++) {
+      temp = this.lYearDays(i)
+      offset -= temp
+    }
+    if (offset < 0) {
+      offset += temp; i--
+    }
+
+    // 是否今天
+    var isTodayObj = new Date()
+    var isToday = false
+    if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) {
+      isToday = true
+    }
+    // 星期几
+    var nWeek = objDate.getDay()
+    var cWeek = this.nStr1[nWeek]
+    // 数字表示周几顺应天朝周一开始的惯例
+    if (nWeek == 0) {
+      nWeek = 7
+    }
+    // 农历年
+    var year = i
+    var leap = this.leapMonth(i) // 闰哪个月
+    var isLeap = false
+
+    // 效验闰月
+    for (i = 1; i < 13 && offset > 0; i++) {
+      // 闰月
+      if (leap > 0 && i == (leap + 1) && isLeap == false) {
+        --i
+        isLeap = true; temp = this.leapDays(year) // 计算农历闰月天数
+      } else {
+        temp = this.monthDays(year, i)// 计算农历普通月天数
+      }
+      // 解除闰月
+      if (isLeap == true && i == (leap + 1)) { isLeap = false }
+      offset -= temp
+    }
+    // 闰月导致数组下标重叠取反
+    if (offset == 0 && leap > 0 && i == leap + 1) {
+      if (isLeap) {
+        isLeap = false
+      } else {
+        isLeap = true; --i
+      }
+    }
+    if (offset < 0) {
+      offset += temp; --i
+    }
+    // 农历月
+    var month = i
+    // 农历日
+    var day = offset + 1
+    // 天干地支处理
+    var sm = m - 1
+    var gzY = this.toGanZhiYear(year)
+
+    // 当月的两个节气
+    // bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year`
+    var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始
+    var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始
+
+    // 依据12节气修正干支月
+    var gzM = this.toGanZhi((y - 1900) * 12 + m + 11)
+    if (d >= firstNode) {
+      gzM = this.toGanZhi((y - 1900) * 12 + m + 12)
+    }
+
+    // 传入的日期的节气与否
+    var isTerm = false
+    var Term = null
+    if (firstNode == d) {
+      isTerm = true
+      Term = this.solarTerm[m * 2 - 2]
+    }
+    if (secondNode == d) {
+      isTerm = true
+      Term = this.solarTerm[m * 2 - 1]
+    }
+    // 日柱 当月一日与 1900/1/1 相差天数
+    var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10
+    var gzD = this.toGanZhi(dayCyclical + d - 1)
+    // 该日期所属的星座
+    var astro = this.toAstro(m, d)
+
+    return { 'lYear': year, 'lMonth': month, 'lDay': day, 'Animal': this.getAnimal(year), 'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month), 'IDayCn': this.toChinaDay(day), 'cYear': y, 'cMonth': m, 'cDay': d, 'gzYear': gzY, 'gzMonth': gzM, 'gzDay': gzD, 'isToday': isToday, 'isLeap': isLeap, 'nWeek': nWeek, 'ncWeek': '\u661f\u671f' + cWeek, 'isTerm': isTerm, 'Term': Term, 'astro': astro }
+  },
+
+  /**
+      * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON
+      * @param y  lunar year
+      * @param m  lunar month
+      * @param d  lunar day
+      * @param isLeapMonth  lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
+      * @return JSON object
+      * @eg:console.log(calendar.lunar2solar(1987,9,10));
+      */
+  lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1
+    var isLeapMonth = !!isLeapMonth
+    var leapOffset = 0
+    var leapMonth = this.leapMonth(y)
+    var leapDay = this.leapDays(y)
+    if (isLeapMonth && (leapMonth != m)) { return -1 }// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
+    if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// 超出了最大极限值
+    var day = this.monthDays(y, m)
+    var _day = day
+    // bugFix 2016-9-25
+    // if month is leap, _day use leapDays method
+    if (isLeapMonth) {
+      _day = this.leapDays(y, m)
+    }
+    if (y < 1900 || y > 2100 || d > _day) { return -1 }// 参数合法性效验
+
+    // 计算农历的时间差
+    var offset = 0
+    for (var i = 1900; i < y; i++) {
+      offset += this.lYearDays(i)
+    }
+    var leap = 0; var isAdd = false
+    for (var i = 1; i < m; i++) {
+      leap = this.leapMonth(y)
+      if (!isAdd) { // 处理闰月
+        if (leap <= i && leap > 0) {
+          offset += this.leapDays(y); isAdd = true
+        }
+      }
+      offset += this.monthDays(y, i)
+    }
+    // 转换闰月农历 需补充该年闰月的前一个月的时差
+    if (isLeapMonth) { offset += day }
+    // 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
+    var stmap = Date.UTC(1900, 1, 30, 0, 0, 0)
+    var calObj = new Date((offset + d - 31) * 86400000 + stmap)
+    var cY = calObj.getUTCFullYear()
+    var cM = calObj.getUTCMonth() + 1
+    var cD = calObj.getUTCDate()
+
+    return this.solar2lunar(cY, cM, cD)
+  }
+}
+
+export default calendar

+ 12 - 0
components/uni-calendar/components/uni-calendar/i18n/en.json

@@ -0,0 +1,12 @@
+{
+	"uni-calender.ok": "ok",
+	"uni-calender.cancel": "cancel",
+	"uni-calender.today": "today",
+	"uni-calender.MON": "MON",
+	"uni-calender.TUE": "TUE",
+	"uni-calender.WED": "WED",
+	"uni-calender.THU": "THU",
+	"uni-calender.FRI": "FRI",
+	"uni-calender.SAT": "SAT",
+	"uni-calender.SUN": "SUN"
+}

+ 8 - 0
components/uni-calendar/components/uni-calendar/i18n/index.js

@@ -0,0 +1,8 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+	en,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant
+}

+ 12 - 0
components/uni-calendar/components/uni-calendar/i18n/zh-Hans.json

@@ -0,0 +1,12 @@
+{
+	"uni-calender.ok": "确定",
+	"uni-calender.cancel": "取消",
+	"uni-calender.today": "今日",
+	"uni-calender.SUN": "日",
+	"uni-calender.MON": "一",
+	"uni-calender.TUE": "二",
+	"uni-calender.WED": "三",
+	"uni-calender.THU": "四",
+	"uni-calender.FRI": "五",
+	"uni-calender.SAT": "六"
+}

+ 12 - 0
components/uni-calendar/components/uni-calendar/i18n/zh-Hant.json

@@ -0,0 +1,12 @@
+{
+	"uni-calender.ok": "確定",
+	"uni-calender.cancel": "取消",
+	"uni-calender.today": "今日",
+	"uni-calender.SUN": "日",
+	"uni-calender.MON": "一",
+	"uni-calender.TUE": "二",
+	"uni-calender.WED": "三",
+	"uni-calender.THU": "四",
+	"uni-calender.FRI": "五",
+	"uni-calender.SAT": "六"
+}

+ 206 - 0
components/uni-calendar/components/uni-calendar/uni-calendar-item.vue

@@ -0,0 +1,206 @@
+<template>
+	<!-- 'uni-calendar-item--checked':(calendar.fullDate === weeks.fullDate && !weeks.isDay) , -->
+	<view class="uni-calendar-item__weeks-box" :class="{
+		'uni-calendar-item--disable':weeks.disable,
+		'uni-calendar-item--before-checked':weeks.beforeMultiple,
+		'uni-calendar-item--multiple': weeks.multiple,
+		'uni-calendar-item--after-checked':weeks.afterMultiple,
+		}"
+	 @click="choiceDate(weeks)"
+	>
+		<view 
+			class="uni-calendar-item__weeks-box-item" 
+			:style="{
+				'background-color':((calendar.fullDate === weeks.fullDate && weeks.isDay) || (calendar.fullDate === weeks.fullDate && !weeks.isDay)) ? '#2979ff' : weeks.extraInfo && weeks.extraInfo.color ? weeks.extraInfo.color : '', 
+				'margin-bottom': weeks.extraInfo && weeks.extraInfo.url ? '0px' : '40rpx'
+			}"
+		>
+			<text v-if="calendar.fullDate === weeks.fullDate" class="uni-calendar-item__weeks-box-circle"></text>
+
+			<text class="uni-calendar-item__weeks-box-text" :class="{
+				'uni-calendar-item--isDay-text': weeks.isDay,
+				'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
+				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
+				'uni-calendar-item--before-checked':weeks.beforeMultiple,
+				'uni-calendar-item--multiple': weeks.multiple,
+				'uni-calendar-item--after-checked':weeks.afterMultiple,
+				'uni-calendar-item--disable':weeks.disable,
+				}">{{weeks.date}}</text>
+
+			<text v-if="!lunar && weeks.isDay" class="uni-calendar-item__weeks-lunar-text" :class="{
+				'uni-calendar-item--isDay-text':weeks.isDay,
+				'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
+				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
+				'uni-calendar-item--before-checked':weeks.beforeMultiple,
+				'uni-calendar-item--multiple': weeks.multiple,
+				'uni-calendar-item--after-checked':weeks.afterMultiple,
+				}">{{todayText}}</text>
+
+			<text v-if="lunar" class="uni-calendar-item__weeks-lunar-text" :class="{
+				'uni-calendar-item--isDay-text':weeks.isDay,
+				'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
+				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
+				'uni-calendar-item--before-checked':weeks.beforeMultiple,
+				'uni-calendar-item--multiple': weeks.multiple,
+				'uni-calendar-item--after-checked':weeks.afterMultiple,
+				'uni-calendar-item--disable':weeks.disable,
+				}">{{weeks.isDay ? todayText : (weeks.lunar.IDayCn === '初一'?weeks.lunar.IMonthCn:weeks.lunar.IDayCn)}}</text>
+
+			<!-- <text v-if="weeks.extraInfo&&weeks.extraInfo.info" class="uni-calendar-item__weeks-lunar-text" :class="{
+				'uni-calendar-item--extra':weeks.extraInfo.info,
+				'uni-calendar-item--isDay-text':weeks.isDay,
+				'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
+				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
+				'uni-calendar-item--before-checked':weeks.beforeMultiple,
+				'uni-calendar-item--multiple': weeks.multiple,
+				'uni-calendar-item--after-checked':weeks.afterMultiple,
+				'uni-calendar-item--disable':weeks.disable,
+				}">{{weeks.extraInfo.info}}</text> -->
+		</view>
+		
+		<view v-if="weeks.extraInfo && weeks.extraInfo.url" style="text-align: center; margin-top: 10px;">
+			<image :src="weeks.extraInfo.url" style="width: 20px; height: 20px;" />
+		</view>
+	</view>
+
+</template>
+
+<script>
+	import { initVueI18n } from '@dcloudio/uni-i18n'
+	import i18nMessages from './i18n/index.js'
+	const {	t	} = initVueI18n(i18nMessages)
+
+	export default {
+		emits:['change'],
+		props: {
+			weeks: {
+				type: Object,
+				default () {
+					return {}
+				}
+			},
+			calendar: {
+				type: Object,
+				default: () => {
+					return {}
+				}
+			},
+			selected: {
+				type: Array,
+				default: () => {
+					return []
+				}
+			},
+			lunar: {
+				type: Boolean,
+				default: false
+			}
+		},
+		computed: {
+			todayText() {
+				return t("uni-calender.today")
+			},
+		},
+		methods: {
+			choiceDate(weeks) {
+				this.$emit('change', weeks)
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	$uni-font-size-base:14px;
+	$uni-text-color:#333;
+	$uni-font-size-sm:12px;
+	$uni-color-error: #e43d33;
+	$uni-opacity-disabled: 0.3;
+	$uni-text-color-disable:#c0c0c0;
+	$uni-primary: #2979ff !default;
+	.uni-calendar-item__weeks-box {
+		flex: 1;
+		/* #ifndef APP-NVUE */
+		// display: flex;
+		/* #endif */
+		// flex-direction: column;
+		// justify-content: center;
+		// align-items: center;
+
+		// border-radius: 4px;
+	}
+
+	.uni-calendar-item__weeks-box-text {
+		font-size: $uni-font-size-base;
+		color: $uni-text-color;
+	}
+
+	.uni-calendar-item__weeks-lunar-text {
+		font-size: $uni-font-size-sm;
+		color: $uni-text-color;
+	}
+
+	.uni-calendar-item__weeks-box-item {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		width: 100rpx;
+		height: 100rpx;
+		border-radius: 4px;
+	}
+
+	.uni-calendar-item__weeks-box-circle {
+		position: absolute;
+		top: 5px;
+		right: 5px;
+		width: 8px;
+		height: 8px;
+		border-radius: 8px;
+		background-color: $uni-color-error;
+
+	}
+
+	.uni-calendar-item--disable {
+		background-color: rgba(249, 249, 249, $uni-opacity-disabled);
+		color: $uni-text-color-disable;
+	}
+
+	.uni-calendar-item--isDay-text {
+		color: $uni-primary;
+	}
+
+	.uni-calendar-item--isDay {
+		background-color: $uni-primary;
+		// opacity: 0.8;
+		color: #fff;
+	}
+
+	.uni-calendar-item--extra {
+		color: $uni-color-error;
+		opacity: 0.8;
+	}
+
+	.uni-calendar-item--checked {
+		background-color: $uni-primary;
+		color: #fff;
+		// opacity: 0.8;
+		border-radius: 4px;
+	}
+
+	.uni-calendar-item--multiple {
+		background-color: $uni-primary;
+		color: #fff;
+		opacity: 0.8;
+	}
+	.uni-calendar-item--before-checked {
+		// background-color: #ff5a5f;
+		// color: #fff;
+	}
+	.uni-calendar-item--after-checked {
+		// background-color: #ff5a5f;
+		// color: #fff;
+	}
+</style>

+ 568 - 0
components/uni-calendar/components/uni-calendar/uni-calendar.vue

@@ -0,0 +1,568 @@
+<template>
+	<view class="uni-calendar">
+		<view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}" @click="clean"></view>
+		<view v-if="insert || show" class="uni-calendar__content" :class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow}">
+			<view v-if="!insert" class="uni-calendar__header uni-calendar--fixed-top">
+				<view class="uni-calendar__header-btn-box" @click="close">
+					<text class="uni-calendar__header-text uni-calendar--fixed-width">{{cancelText}}</text>
+				</view>
+				<view class="uni-calendar__header-btn-box" @click="confirm">
+					<text class="uni-calendar__header-text uni-calendar--fixed-width">{{okText}}</text>
+				</view>
+			</view>
+			<view class="uni-calendar__header">
+				<view class="uni-calendar__header-btn-box" @click.stop="pre">
+					<view class="uni-calendar__header-btn uni-calendar--left"></view>
+				</view>
+				<picker mode="date" :value="date" fields="month" @change="bindDateChange">
+					<text class="uni-calendar__header-text">{{ (nowDate.year||'') +' / '+( nowDate.month||'')}}</text>
+				</picker>
+				<view class="uni-calendar__header-btn-box" @click.stop="next">
+					<view class="uni-calendar__header-btn uni-calendar--right"></view>
+				</view>
+				<text class="uni-calendar__backtoday" @click="backToday">{{todayText}}</text>
+
+			</view>
+			<view class="uni-calendar__box">
+				<view v-if="showMonth" class="uni-calendar__box-bg">
+					<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text>
+				</view>
+				<view class="uni-calendar__weeks">
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{SUNText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{monText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{TUEText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{WEDText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{THUText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{FRIText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{SATText}}</text>
+					</view>
+				</view>
+				<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
+					<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
+						<calendar-item class="uni-calendar-item--hook" :weeks="weeks" :calendar="calendar" :selected="selected" :lunar="lunar" @change="choiceDate"></calendar-item>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import Calendar from './util.js';
+	import CalendarItem from './uni-calendar-item.vue'
+
+	import { initVueI18n } from '@dcloudio/uni-i18n'
+	import i18nMessages from './i18n/index.js'
+	const {	t	} = initVueI18n(i18nMessages)
+
+	/**
+	 * Calendar 日历
+	 * @description 日历组件可以查看日期,选择任意范围内的日期,打点操作。常用场景如:酒店日期预订、火车机票选择购买日期、上下班打卡等
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=56
+	 * @property {String} date 自定义当前时间,默认为今天
+	 * @property {Boolean} lunar 显示农历
+	 * @property {String} startDate 日期选择范围-开始日期
+	 * @property {String} endDate 日期选择范围-结束日期
+	 * @property {Boolean} range 范围选择
+	 * @property {Boolean} insert = [true|false] 插入模式,默认为false
+	 * 	@value true 弹窗模式
+	 * 	@value false 插入模式
+	 * @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容
+	 * @property {Array} selected 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]
+	 * @property {Boolean} showMonth 是否选择月份为背景
+	 * @event {Function} change 日期改变,`insert :ture` 时生效
+	 * @event {Function} confirm 确认选择`insert :false` 时生效
+	 * @event {Function} monthSwitch 切换月份时触发
+	 * @example <uni-calendar :insert="true":lunar="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" />
+	 */
+	export default {
+		components: {
+			CalendarItem
+		},
+		emits:['close','confirm','change','monthSwitch'],
+		props: {
+			date: {
+				type: String,
+				default: ''
+			},
+			selected: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			lunar: {
+				type: Boolean,
+				default: false
+			},
+			startDate: {
+				type: String,
+				default: ''
+			},
+			endDate: {
+				type: String,
+				default: ''
+			},
+			range: {
+				type: Boolean,
+				default: false
+			},
+			insert: {
+				type: Boolean,
+				default: true
+			},
+			showMonth: {
+				type: Boolean,
+				default: true
+			},
+			clearDate: {
+				type: Boolean,
+				default: true
+			}
+		},
+		data() {
+			return {
+				show: false,
+				weeks: [],
+				calendar: {},
+				nowDate: '',
+				aniMaskShow: false
+			}
+		},
+		computed:{
+			/**
+			 * for i18n
+			 */
+
+			okText() {
+				return t("uni-calender.ok")
+			},
+			cancelText() {
+				return t("uni-calender.cancel")
+			},
+			todayText() {
+				return t("uni-calender.today")
+			},
+			monText() {
+				return t("uni-calender.MON")
+			},
+			TUEText() {
+				return t("uni-calender.TUE")
+			},
+			WEDText() {
+				return t("uni-calender.WED")
+			},
+			THUText() {
+				return t("uni-calender.THU")
+			},
+			FRIText() {
+				return t("uni-calender.FRI")
+			},
+			SATText() {
+				return t("uni-calender.SAT")
+			},
+			SUNText() {
+				return t("uni-calender.SUN")
+			},
+		},
+		watch: {
+			date(newVal) {
+				// this.cale.setDate(newVal)
+				this.init(newVal)
+			},
+			startDate(val){
+				this.cale.resetSatrtDate(val)
+				this.cale.setDate(this.nowDate.fullDate)
+				this.weeks = this.cale.weeks
+			},
+			endDate(val){
+				this.cale.resetEndDate(val)
+				this.cale.setDate(this.nowDate.fullDate)
+				this.weeks = this.cale.weeks
+			},
+			selected(newVal) {
+				this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
+				this.weeks = this.cale.weeks
+			}
+		},
+		created() {
+			this.cale = new Calendar({
+				selected: this.selected,
+				startDate: this.startDate,
+				endDate: this.endDate,
+				range: this.range,
+			})
+			this.init(this.date)
+		},
+		methods: {
+			// 取消穿透
+			clean() {},
+			bindDateChange(e) {
+				const value = e.detail.value + '-1'
+				this.setDate(value)
+
+				const { year,month } = this.cale.getDate(value)
+        this.$emit('monthSwitch', {
+            year,
+            month
+        })
+			},
+			/**
+			 * 初始化日期显示
+			 * @param {Object} date
+			 */
+			init(date) {
+				this.cale.setDate(date)
+				this.weeks = this.cale.weeks
+				this.nowDate = this.calendar = this.cale.getInfo(date)
+			},
+			/**
+			 * 打开日历弹窗
+			 */
+			open() {
+				// 弹窗模式并且清理数据
+				if (this.clearDate && !this.insert) {
+					this.cale.cleanMultipleStatus()
+					// this.cale.setDate(this.date)
+					this.init(this.date)
+				}
+				this.show = true
+				this.$nextTick(() => {
+					setTimeout(() => {
+						this.aniMaskShow = true
+					}, 50)
+				})
+			},
+			/**
+			 * 关闭日历弹窗
+			 */
+			close() {
+				this.aniMaskShow = false
+				this.$nextTick(() => {
+					setTimeout(() => {
+						this.show = false
+						this.$emit('close')
+					}, 300)
+				})
+			},
+			/**
+			 * 确认按钮
+			 */
+			confirm() {
+				this.setEmit('confirm')
+				this.close()
+			},
+			/**
+			 * 变化触发
+			 */
+			change(isBackToday = false) {
+				if (!this.insert) return
+				this.setEmit('change', isBackToday)
+			},
+			/**
+			 * 选择月份触发
+			 */
+			monthSwitch() {
+				let {
+					year,
+					month
+				} = this.nowDate
+				this.$emit('monthSwitch', {
+					year,
+					month: Number(month)
+				})
+			},
+			/**
+			 * 派发事件
+			 * @param {Object} name
+			 */
+			setEmit(name, isBackToday = false) {
+				let {
+					year,
+					month,
+					date,
+					fullDate,
+					lunar,
+					extraInfo
+				} = this.calendar
+				this.$emit(name, {
+					range: this.cale.multipleStatus,
+					year,
+					month,
+					date,
+					fulldate: fullDate,
+					lunar,
+					extraInfo: extraInfo || {},
+					isBackToday
+				})
+			},
+			/**
+			 * 选择天触发
+			 * @param {Object} weeks
+			 */
+			choiceDate(weeks) {
+				if (weeks.disable) return
+				this.calendar = weeks
+				// 设置多选
+				this.cale.setMultiple(this.calendar.fullDate)
+				this.weeks = this.cale.weeks
+				this.change()
+			},
+			/**
+			 * 回到今天
+			 */
+			backToday() {
+				const nowYearMonth = `${this.nowDate.year}-${this.nowDate.month}`
+				const date = this.cale.getDate(new Date())
+        const todayYearMonth = `${date.year}-${date.month}`
+
+				this.init(date.fullDate)
+
+        if(nowYearMonth !== todayYearMonth) {
+          this.monthSwitch()
+        }
+
+				this.change(true)
+			},
+			/**
+			 * 上个月
+			 */
+			pre() {
+				const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate
+				this.setDate(preDate)
+				this.monthSwitch()
+
+			},
+			/**
+			 * 下个月
+			 */
+			next() {
+				const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate
+				this.setDate(nextDate)
+				this.monthSwitch()
+			},
+			/**
+			 * 设置日期
+			 * @param {Object} date
+			 */
+			setDate(date) {
+				this.cale.setDate(date)
+				this.weeks = this.cale.weeks
+				this.nowDate = this.cale.getInfo(date)
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	$uni-bg-color-mask: rgba($color: #000000, $alpha: 0.4);
+	$uni-border-color: #EDEDED;
+	$uni-text-color: #333;
+	$uni-bg-color-hover:#f1f1f1;
+	$uni-font-size-base:14px;
+	$uni-text-color-placeholder: #808080;
+	$uni-color-subtitle: #555555;
+	$uni-text-color-grey:#999;
+	.uni-calendar {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+	}
+
+	.uni-calendar__mask {
+		position: fixed;
+		bottom: 0;
+		top: 0;
+		left: 0;
+		right: 0;
+		background-color: $uni-bg-color-mask;
+		transition-property: opacity;
+		transition-duration: 0.3s;
+		opacity: 0;
+		/* #ifndef APP-NVUE */
+		z-index: 99;
+		/* #endif */
+	}
+
+	.uni-calendar--mask-show {
+		opacity: 1
+	}
+
+	.uni-calendar--fixed {
+		position: fixed;
+		/* #ifdef APP-NVUE */
+		bottom: 0;
+		/* #endif */
+		left: 0;
+		right: 0;
+		transition-property: transform;
+		transition-duration: 0.3s;
+		transform: translateY(460px);
+		/* #ifndef APP-NVUE */
+		bottom: calc(var(--window-bottom));
+		z-index: 99;
+		/* #endif */
+	}
+
+	.uni-calendar--ani-show {
+		transform: translateY(0);
+	}
+
+	.uni-calendar__content {
+		background-color: #fff;
+	}
+
+	.uni-calendar__header {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		height: 50px;
+		border-bottom-color: $uni-border-color;
+		border-bottom-style: solid;
+		border-bottom-width: 1px;
+	}
+
+	.uni-calendar--fixed-top {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: space-between;
+		border-top-color: $uni-border-color;
+		border-top-style: solid;
+		border-top-width: 1px;
+	}
+
+	.uni-calendar--fixed-width {
+		width: 50px;
+	}
+
+	.uni-calendar__backtoday {
+		position: absolute;
+		right: 0;
+		top: 25rpx;
+		padding: 0 5px;
+		padding-left: 10px;
+		height: 25px;
+		line-height: 25px;
+		font-size: 12px;
+		border-top-left-radius: 25px;
+		border-bottom-left-radius: 25px;
+		color: $uni-text-color;
+		background-color: $uni-bg-color-hover;
+	}
+
+	.uni-calendar__header-text {
+		text-align: center;
+		width: 100px;
+		font-size: $uni-font-size-base;
+		color: $uni-text-color;
+	}
+
+	.uni-calendar__header-btn-box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		width: 50px;
+		height: 50px;
+	}
+
+	.uni-calendar__header-btn {
+		width: 10px;
+		height: 10px;
+		border-left-color: $uni-text-color-placeholder;
+		border-left-style: solid;
+		border-left-width: 2px;
+		border-top-color: $uni-color-subtitle;
+		border-top-style: solid;
+		border-top-width: 2px;
+	}
+
+	.uni-calendar--left {
+		transform: rotate(-45deg);
+	}
+
+	.uni-calendar--right {
+		transform: rotate(135deg);
+	}
+
+
+	.uni-calendar__weeks {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-calendar__weeks-item {
+		flex: 1;
+	}
+
+	.uni-calendar__weeks-day {
+		flex: 1;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		height: 45px;
+		border-bottom-color: #F5F5F5;
+		border-bottom-style: solid;
+		border-bottom-width: 1px;
+	}
+
+	.uni-calendar__weeks-day-text {
+		font-size: 14px;
+	}
+
+	.uni-calendar__box {
+		position: relative;
+	}
+
+	.uni-calendar__box-bg {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+		position: absolute;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+	}
+
+	.uni-calendar__box-bg-text {
+		font-size: 200px;
+		font-weight: bold;
+		color: $uni-text-color-grey;
+		opacity: 0.1;
+		text-align: center;
+		/* #ifndef APP-NVUE */
+		line-height: 1;
+		/* #endif */
+	}
+</style>

+ 360 - 0
components/uni-calendar/components/uni-calendar/util.js

@@ -0,0 +1,360 @@
+import CALENDAR from './calendar.js'
+
+class Calendar {
+	constructor({
+		date,
+		selected,
+		startDate,
+		endDate,
+		range
+	} = {}) {
+		// 当前日期
+		this.date = this.getDate(new Date()) // 当前初入日期
+		// 打点信息
+		this.selected = selected || [];
+		// 范围开始
+		this.startDate = startDate
+		// 范围结束
+		this.endDate = endDate
+		this.range = range
+		// 多选状态
+		this.cleanMultipleStatus()
+		// 每周日期
+		this.weeks = {}
+		// this._getWeek(this.date.fullDate)
+	}
+	/**
+	 * 设置日期
+	 * @param {Object} date
+	 */
+	setDate(date) {
+		this.selectDate = this.getDate(date)
+		this._getWeek(this.selectDate.fullDate)
+	}
+
+	/**
+	 * 清理多选状态
+	 */
+	cleanMultipleStatus() {
+		this.multipleStatus = {
+			before: '',
+			after: '',
+			data: []
+		}
+	}
+
+	/**
+	 * 重置开始日期
+	 */
+	resetSatrtDate(startDate) {
+		// 范围开始
+		this.startDate = startDate
+
+	}
+
+	/**
+	 * 重置结束日期
+	 */
+	resetEndDate(endDate) {
+		// 范围结束
+		this.endDate = endDate
+	}
+
+	/**
+	 * 获取任意时间
+	 */
+	getDate(date, AddDayCount = 0, str = 'day') {
+		if (!date) {
+			date = new Date()
+		}
+		if (typeof date !== 'object') {
+			date = date.replace(/-/g, '/')
+		}
+		const dd = new Date(date)
+		switch (str) {
+			case 'day':
+				dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
+				break
+			case 'month':
+				if (dd.getDate() === 31 && AddDayCount>0) {
+					dd.setDate(dd.getDate() + AddDayCount)
+				} else {
+					const preMonth = dd.getMonth()
+					dd.setMonth(preMonth + AddDayCount) // 获取AddDayCount天后的日期
+					const nextMonth = dd.getMonth()
+					// 处理 pre 切换月份目标月份为2月没有当前日(30 31) 切换错误问题
+					if(AddDayCount<0 && preMonth!==0 && nextMonth-preMonth>AddDayCount){
+						dd.setMonth(nextMonth+(nextMonth-preMonth+AddDayCount))
+					}
+					// 处理 next 切换月份目标月份为2月没有当前日(30 31) 切换错误问题
+					if(AddDayCount>0 && nextMonth-preMonth>AddDayCount){
+						dd.setMonth(nextMonth-(nextMonth-preMonth-AddDayCount))
+					}
+				}
+				break
+			case 'year':
+				dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期
+				break
+		}
+		const y = dd.getFullYear()
+		const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
+		const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
+		return {
+			fullDate: y + '-' + m + '-' + d,
+			year: y,
+			month: m,
+			date: d,
+			day: dd.getDay()
+		}
+	}
+
+
+	/**
+	 * 获取上月剩余天数
+	 */
+	_getLastMonthDays(firstDay, full) {
+		let dateArr = []
+		for (let i = firstDay; i > 0; i--) {
+			const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate()
+			dateArr.push({
+				date: beforeDate,
+				month: full.month - 1,
+				lunar: this.getlunar(full.year, full.month - 1, beforeDate),
+				disable: true
+			})
+		}
+		return dateArr
+	}
+	/**
+	 * 获取本月天数
+	 */
+	_currentMonthDys(dateData, full) {
+		let dateArr = []
+		let fullDate = this.date.fullDate
+		for (let i = 1; i <= dateData; i++) {
+			let nowDate = full.year + '-' + (full.month < 10 ?
+				full.month : full.month) + '-' + (i < 10 ?
+				'0' + i : i)
+			// 是否今天
+			let isDay = fullDate === nowDate
+			// 获取打点信息
+			let info = this.selected && this.selected.find((item) => {
+				if (this.dateEqual(nowDate, item.date)) {
+					return item
+				}
+			})
+
+			// 日期禁用
+			let disableBefore = true
+			let disableAfter = true
+			if (this.startDate) {
+				// let dateCompBefore = this.dateCompare(this.startDate, fullDate)
+				// disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate)
+				disableBefore = this.dateCompare(this.startDate, nowDate)
+			}
+
+			if (this.endDate) {
+				// let dateCompAfter = this.dateCompare(fullDate, this.endDate)
+				// disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate)
+				disableAfter = this.dateCompare(nowDate, this.endDate)
+			}
+			let multiples = this.multipleStatus.data
+			let checked = false
+			let multiplesStatus = -1
+			if (this.range) {
+				if (multiples) {
+					multiplesStatus = multiples.findIndex((item) => {
+						return this.dateEqual(item, nowDate)
+					})
+				}
+				if (multiplesStatus !== -1) {
+					checked = true
+				}
+			}
+			let data = {
+				fullDate: nowDate,
+				year: full.year,
+				date: i,
+				multiple: this.range ? checked : false,
+				beforeMultiple: this.dateEqual(this.multipleStatus.before, nowDate),
+				afterMultiple: this.dateEqual(this.multipleStatus.after, nowDate),
+				month: full.month,
+				lunar: this.getlunar(full.year, full.month, i),
+				disable: !(disableBefore && disableAfter),
+				isDay
+			}
+			if (info) {
+				data.extraInfo = info
+			}
+
+			dateArr.push(data)
+		}
+		return dateArr
+	}
+	/**
+	 * 获取下月天数
+	 */
+	_getNextMonthDays(surplus, full) {
+		let dateArr = []
+		for (let i = 1; i < surplus + 1; i++) {
+			dateArr.push({
+				date: i,
+				month: Number(full.month) + 1,
+				lunar: this.getlunar(full.year, Number(full.month) + 1, i),
+				disable: true
+			})
+		}
+		return dateArr
+	}
+
+	/**
+	 * 获取当前日期详情
+	 * @param {Object} date
+	 */
+	getInfo(date) {
+		if (!date) {
+			date = new Date()
+		}
+		const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate)
+		return dateInfo
+	}
+
+	/**
+	 * 比较时间大小
+	 */
+	dateCompare(startDate, endDate) {
+		// 计算截止时间
+		startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
+		// 计算详细项的截止时间
+		endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
+		if (startDate <= endDate) {
+			return true
+		} else {
+			return false
+		}
+	}
+
+	/**
+	 * 比较时间是否相等
+	 */
+	dateEqual(before, after) {
+		// 计算截止时间
+		before = new Date(before.replace('-', '/').replace('-', '/'))
+		// 计算详细项的截止时间
+		after = new Date(after.replace('-', '/').replace('-', '/'))
+		if (before.getTime() - after.getTime() === 0) {
+			return true
+		} else {
+			return false
+		}
+	}
+
+
+	/**
+	 * 获取日期范围内所有日期
+	 * @param {Object} begin
+	 * @param {Object} end
+	 */
+	geDateAll(begin, end) {
+		var arr = []
+		var ab = begin.split('-')
+		var ae = end.split('-')
+		var db = new Date()
+		db.setFullYear(ab[0], ab[1] - 1, ab[2])
+		var de = new Date()
+		de.setFullYear(ae[0], ae[1] - 1, ae[2])
+		var unixDb = db.getTime() - 24 * 60 * 60 * 1000
+		var unixDe = de.getTime() - 24 * 60 * 60 * 1000
+		for (var k = unixDb; k <= unixDe;) {
+			k = k + 24 * 60 * 60 * 1000
+			arr.push(this.getDate(new Date(parseInt(k))).fullDate)
+		}
+		return arr
+	}
+	/**
+	 * 计算阴历日期显示
+	 */
+	getlunar(year, month, date) {
+		return CALENDAR.solar2lunar(year, month, date)
+	}
+	/**
+	 * 设置打点
+	 */
+	setSelectInfo(data, value) {
+		this.selected = value
+		this._getWeek(data)
+	}
+
+	/**
+	 *  获取多选状态
+	 */
+	setMultiple(fullDate) {
+		let {
+			before,
+			after
+		} = this.multipleStatus
+
+		if (!this.range) return
+		if (before && after) {
+			this.multipleStatus.before = ''
+			this.multipleStatus.after = ''
+			this.multipleStatus.data = []
+		} else {
+			if (!before) {
+				this.multipleStatus.before = fullDate
+			} else {
+				this.multipleStatus.after = fullDate
+				if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
+					this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
+				} else {
+					this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
+				}
+			}
+		}
+		this._getWeek(fullDate)
+	}
+
+	/**
+	 * 获取每周数据
+	 * @param {Object} dateData
+	 */
+	_getWeek(dateData) {
+		const {
+			year,
+			month
+		} = this.getDate(dateData)
+		let firstDay = new Date(year, month - 1, 1).getDay()
+		let currentDay = new Date(year, month, 0).getDate()
+		let dates = {
+			lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天
+			currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数
+			nextMonthDays: [], // 下个月开始几天
+			weeks: []
+		}
+		let canlender = []
+		const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length)
+		dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData))
+		canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays)
+		let weeks = {}
+		// 拼接数组  上个月开始几天 + 本月天数+ 下个月开始几天
+		for (let i = 0; i < canlender.length; i++) {
+			if (i % 7 === 0) {
+				weeks[parseInt(i / 7)] = new Array(7)
+			}
+			weeks[parseInt(i / 7)][i % 7] = canlender[i]
+		}
+		this.canlender = canlender
+		this.weeks = weeks
+	}
+
+	//静态方法
+	// static init(date) {
+	// 	if (!this.instance) {
+	// 		this.instance = new Calendar(date);
+	// 	}
+	// 	return this.instance;
+	// }
+}
+
+
+export default Calendar

+ 85 - 0
components/uni-calendar/package.json

@@ -0,0 +1,85 @@
+{
+  "id": "uni-calendar",
+  "displayName": "uni-calendar 日历",
+  "version": "1.4.11",
+  "description": "日历组件",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "日历",
+    "",
+    "打卡",
+    "日历选择"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 103 - 0
components/uni-calendar/readme.md

@@ -0,0 +1,103 @@
+
+
+## Calendar 日历
+> **组件名:uni-calendar**
+> 代码块: `uCalendar`
+
+
+日历组件
+
+> **注意事项**
+> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。
+> - 本组件农历转换使用的js是 [@1900-2100区间内的公历、农历互转](https://github.com/jjonline/calendar.js)  
+> - 仅支持自定义组件模式
+> - `date`属性传入的应该是一个 String ,如: 2019-06-27 ,而不是 new Date()
+> - 通过 `insert` 属性来确定当前的事件是 @change 还是 @confirm 。理应合并为一个事件,但是为了区分模式,现使用两个事件,这里需要注意
+> - 弹窗模式下无法阻止后面的元素滚动,如有需要阻止,请在弹窗弹出后,手动设置滚动元素为不可滚动
+
+
+### 安装方式
+
+本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
+
+如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
+
+### 基本用法
+
+在 ``template`` 中使用组件
+
+```html
+<view>
+	<uni-calendar 
+	:insert="true"
+	:lunar="true" 
+	:start-date="'2019-3-2'"
+	:end-date="'2019-5-20'"
+	@change="change"
+	 />
+</view>
+```
+
+### 通过方法打开日历
+
+需要设置 `insert` 为 `false`
+
+```html
+<view>
+	<uni-calendar 
+	ref="calendar"
+	:insert="false"
+	@confirm="confirm"
+	 />
+	 <button @click="open">打开日历</button>
+</view>
+```
+
+```javascript
+
+export default {
+	data() {
+		return {};
+	},
+	methods: {
+		open(){
+			this.$refs.calendar.open();
+		},
+		confirm(e) {
+			console.log(e);
+		}
+	}
+};
+
+```
+
+
+## API
+
+### Calendar Props
+
+|  属性名	|    类型	| 默认值| 说明																													|
+| -	| -	| - | - |
+| date		| String	|-		| 自定义当前时间,默认为今天																							|
+| lunar		| Boolean	| false	| 显示农历																												|
+| startDate	| String	|-		| 日期选择范围-开始日期																									|
+| endDate	| String	|-		| 日期选择范围-结束日期																									|
+| range		| Boolean	| false	| 范围选择																												|
+| insert	| Boolean	| false	| 插入模式,可选值,ture:插入模式;false:弹窗模式;默认为插入模式														|
+|clearDate	|Boolean	|true	|弹窗模式是否清空上次选择内容	|
+| selected	| Array		|-		| 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]	|
+|showMonth	| Boolean	| true	| 是否显示月份为背景																									|
+
+### Calendar Events
+
+|  事件名		| 说明								|返回值|
+| -	|	-	| -	|
+| open	| 弹出日历组件,`insert :false` 时生效|- 	|
+
+
+
+
+
+## 组件示例
+
+点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/calendar/calendar](https://hellouniapp.dcloud.net.cn/pages/extUI/calendar/calendar)

+ 0 - 54
custom-tab-bar/index.js

@@ -1,54 +0,0 @@
-Component({
-  data: {
-    selected: 0,
-		show: true,
-    color: "#7A7E83",
-    selectedColor: "#00B760",
-    list: [
-			{
-				"pagePath": "/pages/index/search",
-				"text": "找人才",
-				"iconPath": "/static/img/search.png",
-				"selectedIconPath": "/static/img/search-fill.png"
-			},
-			{
-				"pagePath": "/pages/index/position",
-				"text": "职位",
-				"iconPath": "/static/img/position.png",
-				"selectedIconPath": "/static/img/position-fill.png"
-			},
-			{
-				"pagePath": "/pages/index/communicate",
-				"text": "沟通",
-				"iconPath": "/static/img/message.png",
-				"selectedIconPath": "/static/img/message-fill.png"
-			},
-			{
-				"pagePath": "/pages/index/jobFair",
-				"text": "招聘会",
-				"iconPath": "/static/img/jobFair.png",
-				"selectedIconPath": "/static/img/jobFair-fill.png"
-			},
-			{
-				"pagePath": "/pages/index/my",
-				"text": "我的",
-				"iconPath": "/static/img/company.png",
-				"selectedIconPath": "/static/img/company-fill.png"
-			}
-		]
-  },
-  lifetimes: {  
-
-  },
-  methods: {
-    switchTab(e) {
-			const data = e.currentTarget.dataset
-      wx.switchTab({
-				url: data.path
-      })
-      this.setData({  
-				selected: data.index  
-      })
-    }
-  }
-})

+ 0 - 4
custom-tab-bar/index.json

@@ -1,4 +0,0 @@
-{
-  "component": true,
-  "usingComponents": {}
-}

+ 0 - 14
custom-tab-bar/index.wxml

@@ -1,14 +0,0 @@
-<!--miniprogram/custom-tab-bar/index.wxml-->
-<view class="tab-bar" style="display: {{ show ? 'flex' : 'none'}}">
-  <view
-    wx:for="{{list}}"
-    wx:key="index"
-    class="tab-bar-item {{ item.center ? 'center' : ''}}"
-    data-path="{{item.pagePath}}"
-    data-index="{{index}}"
-    bindtap="switchTab"
-  >
-    <image src="{{selected === index ? item.selectedIconPath : item.iconPath}}"></image>
-    <view style="color: {{selected === index ? selectedColor : color}};z-index: 1;">{{item.text}}</view>
-  </view>
-</view>

+ 0 - 74
custom-tab-bar/index.wxss

@@ -1,74 +0,0 @@
-.tab-bar {
-  position: fixed;
-  bottom: 0;
-  left: 0;
-  right: 0;
-  height: 60px;
-  background: white;
-  display: flex;
-  padding-bottom: env(safe-area-inset-bottom);
-  border-radius: 20px 20px 0 0;
-  box-shadow: 0px 8px 20px 0px rgba(0,0,0,.5);
-  z-index: 0;
-}
-
-.tab-bar-border {
-  background-color: rgba(0, 0, 0, 0.33);
-  position: absolute;
-  left: 0;
-  top: 0;
-  width: 100%;
-  height: 1px;
-  transform: scaleY(0.5);
-}
-
-.tab-bar-item {
-  flex: 1;
-  text-align: center;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  flex-direction: column;
-  position: relative;
-}
-
-.tab-bar-item.center {
-  margin-top: -20px;
-}
-.tab-bar-item.center image {
-  width: 56px;
-  height: 56px;
-  z-index: 3;
-  border-radius: 50%;
-}
-.tab-bar-item.center::before {
-  content: '';
-  width: 64px;
-  height: 32px;
-  position: absolute;
-  left: 50%;
-  top: 0;
-  transform: translate(-50%, 0px);
-  background: #FFF;
-  border-radius: 180px 180px 0 0 ;
-  box-shadow: 0px 8px 20px 0px rgba(0,0,0,.5);
-  /* clip-path: inset(0 0 66.66% 0); 裁剪三分之一高度 */
-}
-.tab-bar-item.center::after {
-  content: '';
-  width: 100px;
-  height: 40px;
-  position: absolute;
-  left: 50%;
-  top: 20px;
-  background: #FFF;
-  transform: translate(-50%, 0px);
-}
-.tab-bar-item image {
-  width: 27px;
-  height: 27px;
-}
-
-.tab-bar-item view {
-  font-size: 12px;
-}

+ 0 - 95
hooks/useDictionaries.js

@@ -1,95 +0,0 @@
-import {
-  getDictData,
-  getIndustryListData,
-  getSkillList,
-  getIndustryTreeData,
-  getAreaListData,
-  getAreaMapData,
-  getPositionTreeData,
-  getAreaTreeData,
-  getPositionData
-} from '@/api/common'
-import { getSecondNodes } from '@/utils/dealData'
-
-// const setDict = (type, val, cacheTime = 7200) => {
-const setDict = (type, val) => {
-  if (!val) {
-    return
-  }
-  if (type === 'areaTreeData') {
-    const obj = val.data.find(e => e.name === '中国')
-    val.data = obj?.children ? obj.children.map(e =>{
-      // 市辖区直接显示区
-      const municipality = e.children && e.children.length && e.children[0].name === '市辖区'
-      if (municipality && e.children[0].children?.length) e.children = e.children[0].children
-      return e
-    }) : []
-  }
-  if (type === 'areaTreeDataExtend') { // 前排加上不限
-    const obj = val.data.find(e => e.name === '中国')
-    if (obj?.children?.length) {
-      // const province = 
-      obj.children.forEach(e=> {
-        // 市辖区直接显示区
-        const municipality = e.children && e.children.length && e.children[0].name === '市辖区'
-        if (municipality && e.children[0].children?.length) e.children = e.children[0].children
-        // 不限
-        extendFun(e)
-      })
-      val.data = obj.children
-    } else val.data = []
-
-    function extendFun (e) {
-      const idType = Number.isInteger(e.id) ? 'int' : 'str'
-      if(e.children?.length) {
-        e.children.unshift({ name: '不限', id: e.id+'unlimited', idType })
-        e.children.forEach(i => extendFun(i))
-      }
-    }
-  }
-  // 一小时过期
-  const currentTime = new Date()
-  currentTime.setTime(currentTime.getTime() + 3600 * 1000)
-  
-  uni.setStorageSync(type, JSON.stringify({
-    data: val,
-    // expire: Date.now() + cacheTime * 1000
-    expire: currentTime.getTime()
-  }))
-}
-
-export const getDict = (type, params, apiType = 'dict') => {
-    if (!type) {
-      return []
-    }
-    return new Promise((resolve) => {
-      const item = uni.getStorageSync(type)
-      const catchData = item ? JSON.parse(item) : null
-      if (catchData && catchData.expire && (Date.now() <= catchData.expire) && catchData.data && catchData.data?.data?.length) {
-        return resolve({ data: catchData.data })
-      }
-      // 传参按照规范参数传
-      const query = params ? params : { type }
-      const apiFn = {
-        dict: getDictData,
-        positionTreeData: getPositionTreeData, // 职位tree
-        areaTreeData: getAreaTreeData, // 区域tree
-        areaTreeDataExtend: getAreaTreeData, // 区域tree(二级以后含不限)
-        industryTreeData: getIndustryTreeData, // 行业tree
-        industryList: getIndustryListData,
-        skillList: getSkillList,
-        areaList: getAreaListData,
-        areaMap: getAreaMapData,
-        positionSecondData: getPositionTreeData,
-        positionData: getPositionData
-      }
-      apiFn[apiType](query).then(data => {
-        // setDict(type, data, Date.now())
-        if (type === 'positionSecondData') {
-          data.data = getSecondNodes(data.data)
-        }
-        setDict(type, data)
-        resolve({ data })
-      })
-    })
-}

+ 0 - 433
hooks/useIM.js

@@ -1,433 +0,0 @@
-
-
-
-import { ref, onMounted, onUnmounted, watch } from 'vue';
-import { getConversationSync, getMessageSync, getChatKey, setUnread, deleteConversation } from '@/api/common'
-import { Base64 } from 'js-base64'
-
-import { userStore } from '@/store/user'
-import { useIMStore } from '@/store/im'
-
-// 配置悟空IM
-import {
-  MessageText,
-  Channel,
-  WKSDK,
-  ChannelTypePerson,
-  MessageContent,
-} from "wukongimjssdk"
-
-// 默认招呼语
-export const defaultText = '您好,我们正在寻找充满激情、勇于挑战的您,快来和我聊一聊吧~'
-
-const { ObjectContent } = initRegister(101)
-const { ObjectContent: ObjectContent2 } = initRegister(102)
-const { ObjectContent: ObjectContent3 } = initRegister(103)
-const { ObjectContent: ObjectContent4 } = initRegister(104)
-const { ObjectContent: ObjectContent5 } = initRegister(105) // 发送简历
-
-
-const contentType = {
-  101: ObjectContent,
-  102: ObjectContent2,
-  103: ObjectContent3,
-  104: ObjectContent4,
-  105: ObjectContent5, // 发送简历
-}
-
-// 注册消息体
-function initRegister (type) {
-  class ObjectContent extends MessageContent {
-    constructor(text) {
-      super();
-      this.content = text
-    }
-    get conversationDigest() {
-        // 这里需要实现具体的逻辑
-        return this.content
-    }
-    get contentType() {
-        // 这里需要实现具体的逻辑
-        return type; // 示例实现
-    }
-    decodeJSON(content) {
-        this.content = content.text;
-    }
-    encodeJSON() {
-        return {
-          content: this.content
-        };
-    }
-  }
-  // 注册101类型为面试
-  WKSDK.shared().register(type, () => new ObjectContent(''))
-  return {
-    ObjectContent
-  }
-}
-
-
-const HISTORY_QUERY = {
-  limit: 20,
-  startMessageSeq: 0,
-  endMessageSeq: 0,
-  pullMode: 1
-}
-
-const ConnectStatus = {
-  Disconnect: 0, // 断开连接
-  Connected: 1, // 连接成功
-  Connecting: 2, // 连接中
-  ConnectFail: 3, // 连接错误
-  ConnectKick: 4, // 连接被踢,服务器要求客户端断开(一般是账号在其他地方登录,被踢)
-}
-// api 接入
-export function useDataSource () {
-  const useUserStore = userStore()
-  // 最近会话数据源
-  WKSDK.shared().config.provider.syncConversationsCallback  = async () => {
-    const query = {
-      msg_count: 1,
-      enterpriseId: useUserStore?.userInfo?.enterpriseId
-    }
-
-    const resultConversations = []
-    const resp = await getConversationSync(query)
-    const { data:conversationList } = resp
-    if (conversationList) {
-      conversationList.forEach(conversation => {
-        conversation.channel = new Channel(conversation.channel_id, conversation.channel_type)
-        conversation.unread = +(conversation.unread || 0)
-        resultConversations.push(conversation)
-      })
-    }
-    return resultConversations
-  }
-    // 同步频道消息数据源
-  WKSDK.shared().config.provider.syncMessagesCallback = async function(channel) {
-    // 后端提供的获取频道消息列表的接口数据 然后构建成 Message对象数组返回
-    let resultMessages  = new Array()
-    const {
-      startMessageSeq: start_message_seq,
-      endMessageSeq: end_message_seq,
-      limit,
-      pullMode: pull_mode
-    } = HISTORY_QUERY
-    const query = {
-      channel_id: channel.channelID,
-      channel_type: channel.channelType,
-      enterpriseId: useUserStore?.userInfo?.enterpriseId,
-      start_message_seq,
-      end_message_seq,
-      limit,
-      pull_mode,
-    }
-
-    const { data } = await getMessageSync(query)
-    const resp = data
-    const messageList = resp && resp["messages"]
-    if (messageList) {
-      messageList.forEach((msg) => {
-        // const message = Convert.toMessage(msg);
-        // msg.channel = new Channel(msg.channel_id, msg.channel_type)
-        msg.payload = JSON.parse(Base64.decode(msg.payload))
-        if (contentType[msg.payload.type]) {
-          msg.payload.content = JSON.parse(msg.payload.content ?? '{}')
-        }
-        resultMessages.push(msg)
-      })
-    }
-    // console.log(resultMessages)
-    const more = resp.more === 1
-    return {
-      more,
-      resultMessages
-    }
-  }
-}
-
-export function toChannel (channelID, channelType) {
-  return new Channel(channelID, channelType)
-}
-
-async function getKey () {
-  const useUserStore = userStore()
-  if (!useUserStore.accountInfo?.userId) {
-    return {}
-  }
-  const keyQuery = {
-    userId: useUserStore.accountInfo?.userId,
-    enterpriseId: useUserStore?.userInfo?.enterpriseId
-  }
-
-  const { data } = await getChatKey(keyQuery)
-  return {
-    ...data
-  }
-}
-
-export const useIM = () => {
-  useDataSource()
-  const key = ref(0)
-  const IM = useIMStore()
-  
-  onMounted( async () => {
-    await resetConfig()
-    // 连接状态监听
-    WKSDK.shared().connectManager.addConnectStatusListener(connectStatusListener)
-    // 常规消息监听
-    WKSDK.shared().chatManager.addMessageListener(messageListen)
-    // 连接
-    WKSDK.shared().connectManager.connect()
-  })
-  onUnmounted(() => {
-    WKSDK.shared().connectManager.removeConnectStatusListener(connectStatusListener)
-    // 常规消息监听移除
-    WKSDK.shared().chatManager.removeMessageListener(messageListen)
-    // 连接状态监听移除
-    WKSDK.shared().connectManager.disconnect()
-  })
-  
-  async function messageListen (message) {
-    // console.log('收到消息', message)
-    IM.setFromChannel(message.channel.channelID)
-    setUnreadCount()
-  }
-
-  async function connectStatusListener (status) {
-    // console.log('连接状态', status === ConnectStatus.Connected)
-    // 连接成功 获取点击数
-    const connected = status === ConnectStatus.Connected
-    IM.setConnected(connected)
-    if (connected) {
-      // 必须同步最近会话才能获取未读总数
-      await syncConversation()
-      setUnreadCount()
-    }
-  }
-
-  function setUnreadCount () {
-    const count = WKSDK.shared().conversationManager.getAllUnreadCount()
-    key.value++
-    IM.setNewMsg(key.value)
-    IM.setUnreadCount(count)
-    console.log('未读消息总数', count)
-  }
-
-  async function resetConfig () {
-    try {
-      const { uid, wssUrl, token } = await getKey()
-      IM.setUid(uid)
-      // 单机模式可以直接设置地址
-      WKSDK.shared().config.addr = 'wss://' + wssUrl// 默认端口为5200 + wsUrl 
-      // 认证信息
-      WKSDK.shared().config.uid = uid // 用户uid(需要在悟空通讯端注册过)
-      WKSDK.shared().config.token = token // 用户token (需要在悟空通讯端注册过)
-    } catch (error) {
-      console.log(error)
-    }
-  }
-
-  return {
-    resetConfig
-  }
-}
-
-export function initConnect (callback = () => {}, mounted = () => {}) {
-  useDataSource()
-  const IM = useIMStore()
-  const conversationList = ref([])
-  const messageItems = ref([])
-
-  watch(
-    () => IM.newMsg,
-    async () => {
-      // 未读消息变化
-      updateConversation()
-      // 拉取最新消息 查看是否是自己的数据
-    },
-    {
-      deep: true,
-      immediate: true
-    }
-  )
-  onMounted(async () => {
-    // 消息发送状态监听
-    WKSDK.shared().chatManager.addMessageStatusListener(statusListen)
-    // 常规消息监听
-    // WKSDK.shared().chatManager.addMessageListener(messageListen)
-
-    mounted()
-  })
-  onUnmounted(() => {
-    // 消息发送状态监听移除
-    WKSDK.shared().chatManager.removeMessageStatusListener(statusListen)
-    // 常规消息监听移除
-    // WKSDK.shared().chatManager.removeMessageListener(messageListen)
-  })
-
-  // 消息发送状态监听
-  function statusListen (packet) {
-    console.log('发送状态', packet)
-    if (packet.reasonCode === 1) {
-      // 发送成功
-      console.log('发送成功')
-      // 添加一组成功数据
-      callback(true)
-    } else {
-      // 发送失败
-      console.log('发送失败')
-      // 添加一组失败数据
-      callback(false)
-    }
-  }
-
-  async function updateConversation () {
-    const res = await syncConversation()
-    conversationList.value = res
-  }
-
-  function updateUnreadCount () {
-    const count = WKSDK.shared().conversationManager.getAllUnreadCount()
-    IM.setUnreadCount(count)
-  } 
-
-  async function deleteConversations (channel, enterpriseId) {
-    const query = {
-      channel_id: channel.channelID,
-      channel_type: channel.channelType,
-      enterpriseId
-    }
-    await deleteConversation(query)
-  }
-
-  async function resetUnread (channel, enterpriseId) {
-    const query = {
-      channel_id: channel.channelID,
-      channel_type: channel.channelType,
-      enterpriseId,
-      unread: 0
-    }
-    const res = await setUnread(query)
-    return res
-  }
-
-  return {
-    resetUnread,
-    deleteConversations,
-    updateConversation,
-    updateUnreadCount,
-    conversationList,
-    messageItems,
-    // channel
-  }
-}
-
-// 同步最近会话
-async function syncConversation () {
-  const res = await WKSDK.shared().conversationManager.sync()
-  return res
-}
-
-// 发起聊天
-export async function initChart (userId, enterpriseId) {
-  try {
-    const channel = ref()
-    // const list = ref([])
-    const query = {
-      userId,
-      enterpriseId
-    }
-    // 创建聊天频道
-    const { data } = await getChatKey(query)
-    // console.log(data, 'data')
-    const { uid } = data
-    const _channel = new Channel(uid, ChannelTypePerson)
-    channel.value = _channel
-    const conversation = WKSDK.shared().conversationManager.findConversation(_channel)
-    if(!conversation) {
-      // 如果最近会话不存在,则创建一个空的会话
-      WKSDK.shared().conversationManager.createEmptyConversation(_channel)
-    }
-    const res = await getMoreMessages(1, _channel)
-    return {
-      channel,
-      ...res
-    }
-  } catch (error) {
-    console.log(error)
-  }
-}
-
-// 翻页
-export async function getMoreMessages (pageSize, channel) {
-  const list = ref([])
-  Object.assign(HISTORY_QUERY, {
-    startMessageSeq: (pageSize - 1) * HISTORY_QUERY.limit
-  })
-  const { resultMessages, more } = await WKSDK.shared().chatManager.syncMessages(channel)
-  list.value = resultMessages
-  return {
-    list,
-    more
-  }
-}
-
-/**
- * 
- * @param {*} text 
- * @param {*} _channel 
- * @param { Number } type : 101 面试主体 
- * @returns 
- */
-  // 发送职位使用101
-export function send (text, _channel, type) {
-  let _text
-  if (contentType[type]) {
-    _text = new contentType[type](text)
-    WKSDK.shared().chatManager.send(_text, _channel)
-    return
-  }
-  _text = new MessageText(text)
-  console.log(WKSDK.shared().chatManager, 111111)
-  WKSDK.shared().chatManager.send(_text, _channel)
-}
-
-// 对话开场白 用户 to 企业
-export async function prologue ({userId, enterpriseId, text}) {
-  const { channel } = await checkConversation(userId, enterpriseId)
-  send(text, channel, 102)
-  return channel
-}
-
-// 企业 to 用户
-export async function talkToUser ({userId, text}) {
-  const { channel, isNewTalk } = await checkConversation(userId)
-  // if (!isNewTalk) send(text, channel)
-  send(text, channel)
-  return channel
-}
-
-// 检测是否存在频道
-export async function checkConversation (userId, enterpriseId) {
-  const query = {
-    userId,
-    enterpriseId
-  }
-  // 创建聊天频道
-  const { data } = await getChatKey(query)
-  const { uid } = data
-  const _channel = new Channel(uid, ChannelTypePerson)
-  console.log('生成channel', _channel)
-  const conversation = WKSDK.shared().conversationManager.findConversation(_channel)
-  const isNewTalk = ref(false)
-  if(!conversation) {
-    // 如果最近会话不存在,则创建一个空的会话
-    WKSDK.shared().conversationManager.createEmptyConversation(_channel)
-    isNewTalk.value = true
-  }
-  return {
-    channel: _channel,
-    isNewTalk: isNewTalk.value
-  }
-}

+ 2 - 2
main.js

@@ -22,8 +22,8 @@ const pinia = createPinia()
 pinia.use(piniaPluginPersistedstate)
 
 // 第三方字体库调用
-import { loadFont } from './utils/font.js'
-loadFont() // 下载字体
+// import { loadFont } from './utils/font.js'
+// loadFont() // 下载字体
 
 export function createApp() {
   const app = createSSRApp(App)

+ 2 - 2
manifest.json

@@ -1,5 +1,5 @@
 {
-    "name" : "menduner",
+    "name" : "我是大女主",
     "appid" : "",
     "description" : "",
     "versionName" : "1.0.0",
@@ -50,7 +50,7 @@
     /* 快应用特有相关 */
     "mp-weixin" : {
         /* 小程序特有相关 */
-        "appid" : "wx247547be545cfc27",
+        "appid" : "wx6decdf12f9e7a061",
         "setting" : {
             "urlCheck" : false
         },

+ 3 - 290
pages.json

@@ -1,303 +1,16 @@
 {
 	"pages": [
 		{
-			"path": "pages/index/loading",
+			"path": "pages/drawLots/index",
 			"style": {
-				"navigationBarTitleText": "门墩儿 专注顶尖招聘"
+				"navigationBarTitleText": ""
 			}
-		},
-		{
-			"path": "pages/index/search",
-			"style": {
-				"navigationBarTitleText": "人才推荐",
-				"navigationStyle": "custom"
-			}
-		},
-		{
-			"path": "pages/index/position",
-			"style": {
-				"navigationBarTitleText": "职位",
-				"navigationStyle": "custom"
-			}
-		},
-		{
-			"path": "pages/register/index",
-			"style": {
-				"navigationBarTitleText": "企业注册"
-			}
-		},
-		{
-			"path": "pages/register/contact",
-			"style": {
-				"navigationBarTitleText": "企业注册-联系人填写"
-			}
-		},
-		{
-			"path": "pages/register/review",
-			"style": {
-				"navigationBarTitleText": "账号注册进度"
-			}
-		},
-		{
-			"path": "pages/register/phoneValidate",
-			"style": {
-				"navigationBarTitleText": "手机号效验"
-			}
-		},
-		{
-			"path": "pages/index/communicate",
-			"style": {
-				"navigationBarTitleText": "最近联系人",
-				"navigationStyle": "custom"
-			}
-		},
-		{
-			"path": "pages/index/jobFair",
-			"style": {
-				"navigationBarTitleText": "招聘会",
-				"navigationStyle": "custom"
-			}
-		},
-		{
-			"path": "pages/index/my",
-			"style": {
-				"navigationBarTitleText": "我的",
-				"navigationStyle": "custom"
-			}
-		},
-		{
-			"path": "pages/addWebView/index",
-			"style": {
-				"navigationBarTitleText": ""
-			}
-		}
-	],
-	"subPackages": [
-		{
-			"root": "pagesA",
-			"pages": [
-				{
-					"path": "interview/index",
-					"style": {
-						"navigationBarTitleText": "面试管理"
-					}
-				},
-				{
-					"path": "interview/feedback",
-					"style": {
-						"navigationBarTitleText": "面试反馈"
-					}
-				},
-				{
-					"path": "interview/cancel",
-					"style": {
-						"navigationBarTitleText": "取消面试"
-					}
-				},
-				{
-					"path": "interview/attended",
-					"style": {
-						"navigationBarTitleText": "面试爽约"
-					}
-				},
-				{
-					"path": "chart/index",
-					"style": {
-						"navigationBarTitleText": "我的聊天",
-						"navigationStyle": "custom"
-					}
-				},
-				{
-					"path": "resume/index",
-					"style": {
-						"navigationBarTitleText": "简历管理"
-					}
-				},
-				{
-					"path": "editPassword/index",
-					"style": {
-						"navigationBarTitleText": "修改登录密码"
-					}
-				},
-				{
-					"path": "forgotPassword/index",
-					"style": {
-						"navigationBarTitleText": "忘记密码"
-					}
-				}
-			]
-		},
-		{
-			"root": "pagesB",
-			"pages": [
-				{
-					"path": "personnelDetails/index",
-					"style": {
-						"navigationBarTitleText": "人才详情"
-					}
-				},
-				{
-					"path": "contactUs/index",
-					"style": {
-						"navigationBarTitleText": "联系我们"
-					}
-				},
-				{
-					"path": "positionDetail/index",
-					"style": {
-						"navigationBarTitleText": "职位详情"
-					}
-				},
-				{
-					"path": "positionAdd/index",
-					"style": {
-						"navigationBarTitleText": "新增职位"
-					}
-				},
-				{
-					"path": "positionAdd/select",
-					"style": {
-						"navigationBarTitleText": "新增职位方式选择"
-					}
-				},
-				{
-					"path": "positionEdit/index",
-					"style": {
-						"navigationBarTitleText": "编辑职位"
-					}
-				},
-				{
-					"path": "agreement/index",
-					"style": {
-						"navigationBarTitleText": "协议中心"
-					}
-				},
-				{
-					"path": "staffInfoEdit/index",
-					"style": {
-						"navigationBarTitleText": "员工信息编辑"
-					}
-				},
-				{
-					"path": "companyInfoEdit/index",
-					"style": {
-						"navigationBarTitleText": "企业基本信息编辑"
-					}
-				},
-				{
-					"path": "agreement/user",
-					"style": {
-						"navigationBarTitleText": "用户协议"
-					}
-				},
-				{
-					"path": "agreement/privacy",
-					"style": {
-						"navigationBarTitleText": "隐私协议"
-					}
-				},
-				{
-					"path": "agreement/CopyrightPolicy",
-					"style": {
-						"navigationBarTitleText": "版权政策"
-					}
-				},
-				{
-					"path": "agreement/WorkplaceCommunityPolicy",
-					"style": {
-						"navigationBarTitleText": "职场社区政策"
-					}
-				},
-				{
-					"path": "agreement/UserBehaviorNorms",
-					"style": {
-						"navigationBarTitleText": "用户行为规范"
-					}
-				},
-				{
-					"path": "jobFair/details",
-					"style": {
-						"navigationBarTitleText": "招聘会详情"
-					}
-				},
-				{
-					"path": "jobFair/join",
-					"style": {
-						"navigationBarTitleText": "职位加入到招聘会"
-					}
-				},
-				{
-					"path": "jobFair/jobFairEntShare",
-					"style": {
-						"navigationBarTitleText": "分享招聘会企业"
-					}
-				},
-				{
-					"path": "InviteInterview/index",
-					"style": {
-						"navigationBarTitleText": "邀请面试"
-					}
-				},
-				{
-					"path": "jobFair/addJob",
-					"style": {
-						"navigationBarTitleText": "招聘会职位新增"
-					}
-				},
-				{
-					"path": "jobFair/editJob",
-					"style": {
-						"navigationBarTitleText": "招聘会职位编辑"
-					}
-				}
-			]
 		}
 	],
 	"globalStyle": {
 		"navigationBarTextStyle": "black",
-		"navigationBarTitleText": "门墩儿招聘",
+		"navigationBarTitleText": "我是大女主",
 		"navigationBarBackgroundColor": "#ffffff",
 		"backgroundColor": "#ffffff"
-	},
-	"tabBar": {
-		"color": "#7A7E83",
-		"selectedColor": "#00B760",
-		"borderStyle": "black",
-		"backgroundColor": "#ffffff",
-		"height": "65px",
-		"custom": true,
-		"fontSize": "24rpx",
-		"list": [
-			{
-				"pagePath": "pages/index/search",
-				"text": "找人才",
-				"iconPath": "/static/img/search.png",
-				"selectedIconPath": "/static/img/search-fill.png"
-			},
-			{
-				"pagePath": "pages/index/position",
-				"text": "职位",
-				"iconPath": "/static/img/position.png",
-				"selectedIconPath": "/static/img/position-fill.png"
-			},
-			{
-				"pagePath": "pages/index/communicate",
-				"text": "沟通",
-				"iconPath": "/static/img/message.png",
-				"selectedIconPath": "/static/img/message-fill.png"
-			},
-			{
-				"pagePath": "pages/index/jobFair",
-				"text": "招聘会",
-				"iconPath": "/static/img/jobFair.png",
-				"selectedIconPath": "/static/img/jobFair-fill.png"
-			},
-			{
-				"pagePath": "pages/index/my",
-				"text": "我的",
-				"iconPath": "/static/img/company.png",
-				"selectedIconPath": "/static/img/company-fill.png"
-			}
-		]
 	}
 }

+ 113 - 0
pages/drawLots/index.vue

@@ -0,0 +1,113 @@
+<template>
+  <view>
+		<Calendar
+			class="uni-calendar--hook"
+			:selected="selected"
+			:lunar="true"
+			:range="false"
+			:showMonth="true"
+			@change="handleChange"
+		/>
+
+		<uni-popup ref="popupRef" type="dialog">
+			<view class="popupContent">
+				<view class="">上上签</view>
+				<view class="ss-m-y-10">今日运势:上</view>
+				<view class="d-flex align-center justify-center">
+					幸运色:
+					<view class="luckyColor" :style="{ 'background-color': currentColor }"></view>
+				</view>
+
+				<view class="color-666 font-size-13 ss-m-t-30" style="text-align: left;">
+					<view>宜:炼丹悟道 结善缘 精心修养</view>
+					<view>忌:远行 投资 冲动决策</view>
+					<view>今日贵人相助,修行精进</view>
+				</view>
+			</view>
+		</uni-popup>
+  </view>
+</template>
+
+<script setup>
+import { onLoad } from '@dcloudio/uni-app'
+import { ref } from 'vue'
+import Calendar from '@/components/uni-calendar/components/uni-calendar/uni-calendar.vue'
+
+	/**
+	 * 获取任意时间
+	 */
+	function getDate(date, AddDayCount = 0) {
+		if (!date) {
+			date = new Date()
+		}
+		if (typeof date !== 'object') {
+			date = date.replace(/-/g, '/')
+		}
+		const dd = new Date(date)
+
+		dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
+
+		const y = dd.getFullYear()
+		const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
+		const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
+		return {
+			fullDate: y + '-' + m + '-' + d,
+			year: y,
+			month: m,
+			date: d,
+			day: dd.getDay()
+		}
+	}
+
+	const selected = ref([])
+
+	onLoad(() => {
+		setTimeout(() => {
+			selected.value = [
+				{
+					date: getDate(new Date(),-3).fullDate,
+					color: '#2196F3',
+					url: 'https://menduner.citupro.com:3443/dev/2dbc20a5db2122e399b491638889ba9f8aea4e1c7a44463ee0df40b25f85b8cc.png'
+				},
+				{
+					date: getDate(new Date(),-2).fullDate,
+					color: '#ff5252',
+					url: 'https://menduner.citupro.com:3443/dev/2dbc20a5db2122e399b491638889ba9f8aea4e1c7a44463ee0df40b25f85b8cc.png'
+				},
+				{
+					date: getDate(new Date(),-1).fullDate,
+					color: '#26A69A',
+					url: 'https://menduner.citupro.com:3443/dev/2dbc20a5db2122e399b491638889ba9f8aea4e1c7a44463ee0df40b25f85b8cc.png'
+				}
+			]
+		}, 2000)
+	})
+
+
+	const popupRef = ref()
+	const currentColor = ref(null)
+	const handleChange = (e) => {
+		// console.log('change 返回:', e)
+		if (e.isBackToday) return
+		if (e.extraInfo) {
+			popupRef.value.open()
+			currentColor.value = e.extraInfo?.color || '#2979ff'
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+.popupContent {
+	background-color: #fff;
+	border-radius: 6px;
+	width: 400rpx;
+	height: 400rpx;
+	text-align: center;
+	padding: 30rpx;
+	.luckyColor {
+		width: 60rpx;
+		height: 60rpx;
+		border-radius: 50%;
+	}
+}
+</style>

+ 0 - 236
pages/index/communicate.vue

@@ -1,236 +0,0 @@
-<template>
-  <view>
-		<Navbar title="最近联系人" />
-		<layout-page>
-			<view :style="{'padding-top': navbarHeight + 'px'}">
-				<view class="commonBackground"></view>
-				<view class="height defaultBgc">
-					<scroll-view class="scrollBox" scroll-y="true" >
-						<view class="box" v-for="item in items" :key="item.id" @tap="handleTo(item)">
-							<view class="box-header">
-								<template v-if="item.unread === '0'">
-									<image
-										class="enterAvatar"
-										:src="getUserAvatar(item?.userInfoVo?.userInfoResp?.avatar, item?.userInfoVo?.userInfoResp?.sex, !item?.userInfoVo && item.channel_id === 'system' ? true : false)"
-									></image>
-								</template>
-								<template v-else>
-									<uni-badge class="uni-badge-left-margin" :text="item.unread" absolute="rightTop" size="small">
-										<image
-											class="enterAvatar"
-											:src="getUserAvatar(item?.userInfoVo?.userInfoResp?.avatar, item?.userInfoVo?.userInfoResp?.sex, !item?.userInfoVo && item.channel_id === 'system' ? true : false)"
-										></image>
-									</uni-badge>
-								</template>
-							</view>
-							<view class="box-content">
-								<view class="box-content-names">
-									<view class="name">
-										{{ item.thatName }}
-										<text class="nameSub">{{ formatName(item.enterpriseAnotherName) }}</text>
-										<span class="line" v-if="item.postNameCn && item.enterpriseAnotherName"></span>
-										<text class="nameSub">{{ item.postNameCn }}</text>
-									</view>
-								</view>
-								<view class="box-content-text">{{ timesTampChange(+item.timestamp.padEnd(13, '0')) }}</view>
-							</view>
-						</view>
-						<image
-							v-if=" items.length===0 "
-							src="https://minio.menduner.com/dev/bb43df1dc91945e05ee93da76e49b34f87b0d10203eb76c20e2d4999a13b9a0a.png"
-							mode="widthFix"
-							style="width: 100%;">
-						</image>
-						<uni-load-more status="noMore" />
-					</scroll-view>
-				</view>
-			</view>
-		</layout-page>
-	</view>
-</template>
-
-<script setup>
-import { ref, watch, computed } from 'vue'
-import layoutPage from '@/layout'
-import Navbar from '@/components/Navbar'
-import { getConversationSync } from '@/api/common'
-import { onShow, onLoad, onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
-import { getUserAvatar } from '@/utils/avatar'
-import { timesTampChange } from '@/utils/date'
-import { userStore } from '@/store/user'
-import { useIMStore } from '@/store/im'
-import { formatName } from '@/utils/getText'
-
-const useUserStore = userStore()
-const userInfo = computed(() => useUserStore?.userInfo)
-const navbarHeight = ref(uni.getStorageSync('navbarHeight'))
-
-const IM = useIMStore()
-
-
-const items = ref([])
-watch([() => useUserStore.refreshToken, () => IM.newMsg], () => {
-	if (!useUserStore.refreshToken) return items.value = []
-	// 检测实例是否存在
-	if (!IM.uid?.value) {
-		return
-	}
-	if (!userInfo?.enterpriseId) setTimeout(() => {
-		init()
-	}, 2000)
-	
-}, { deep: true })
-
-watch(() => IM.uid, (val) => {
-	if (!val) {
-		items.value = []
-		return
-	}
-	// 监听uid变化
-	if (!userInfo?.enterpriseId) setTimeout(() => {
-		init()
-	}, 2000)
-})
-
-onShow(() => {
-	const currentPage = getCurrentPages()[0];  // 获取当前页面实例
-	const currentTabBar = currentPage?.getTabBar?.();
-
-	// 设置当前tab页的下标index
-	currentTabBar?.setData({ selected: 2 });
-	init()
-})
-
-onLoad(() => {
-  wx.showShareMenu({
-    withShareTicket: true,
-    menus: ['shareAppMessage', 'shareTimeline']
-  })
-  onShareAppMessage(() => {
-    return {
-      title: '门墩儿 专注顶尖招聘',
-      path: '/pages/index/position',
-			imageUrl: '../../static/img/share-poster.jpg'
-    }
-  })
-	onShareTimeline(() => {
-    return {
-      title: '门墩儿 专注顶尖招聘',
-      path: '/pages/index/position',
-			imageUrl: '../../static/img/share-poster.jpg'
-    }
-  })
-})
-
-
-
-const handleTo = (item) => {
-	const { userInfoVo, thatName, postNameCn, enterpriseAnotherName, channel_id, channel_type } = item
-	const query = {
-		id: userInfoVo?.userInfoResp?.userId,
-		name: thatName,
-		channelID: channel_id,
-		channelType: channel_type,
-		avatar: userInfoVo?.userInfoResp?.avatar,
-		sex: userInfoVo?.userInfoResp?.sex,
-	}
-	const queryStr = Object.keys(query).reduce((r, v) => {
-		if (!query[v]) {
-			return r
-		}
-		return r += `${v}=${encodeURIComponent(query[v])}&`
-	}, '?')
-	uni.navigateTo({
-    url: `/pagesA/chart/index${queryStr.slice(0, -1)}`
-  })
-}
-
-async function init () {
-	try {
-		const { data } = await getConversationSync({ msg_count: 1, enterpriseId: userInfo.value.enterpriseId })
-		if (!data) {
-			return
-		}
-		items.value = data.map(item => {
-			return {
-				thatName: item?.userInfoVo ? (item.userInfoVo.userInfoResp?.name ? item.userInfoVo.userInfoResp.name : item.userInfoVo.userInfoResp.phone) : '系统消息',
-				enterpriseAnotherName: item?.userInfoVo?.userInfoResp?.enterpriseAnotherName || item?.userInfoVo?.userInfoResp?.enterpriseName,
-				postNameCn: item?.userInfoVo?.userInfoResp?.postNameCn ?? '',
-				...item
-			}
-		})
-	} catch (error) {
-	}
-}
-
-</script>
-
-<style scoped lang="scss">
-.scrollBox {
-  box-sizing: border-box;
-}
-.box {
-	height: 130rpx;
-	padding: 20rpx;
-	box-sizing: border-box;
-	display: flex;
-	border-bottom: 2rpx solid #eee;
-	&-header {
-		width: 120rpx;
-		height: 100%;
-		position: relative;
-	}
-	&-content {
-		flex: 1;
-		width: 0;
-		display: flex;
-		flex-direction: column;
-		justify-content: space-between;
-		&-names {
-			display: flex;
-			justify-content: space-between;
-			
-			.name {
-				flex: 1;
-				overflow: hidden;
-				white-space: nowrap;
-				text-overflow: ellipsis;
-				.nameSub {
-					font-size: 0.75em;
-					color: #999;
-				}
-				.line {
-					display: inline-block;
-					width: 2rpx;
-					height: 24rpx;
-					vertical-align: middle;
-					background-color: #e0e0e0;
-					margin: 0 6rpx;
-				}
-			}
-			.time {
-				color: #999;
-				font-size: .85em;
-			}
-		}
-		&-text {
-			color: #999;
-			font-size: .85em;
-			overflow: hidden;
-			white-space: nowrap;
-			text-overflow: ellipsis;
-		}
-	}
-}
-.height {
-	height: 100vh;
-	padding-bottom: 100px;
-	box-sizing: border-box;
-}
-.enterAvatar{
-	width: 80rpx;
-	height: 80rpx;
-	border-radius: 50%;
-	margin: 0 auto;
-}
-</style>

+ 0 - 156
pages/index/components/condition.vue

@@ -1,156 +0,0 @@
-<template>
-	<view class="box defaultBgc">
-		<view>
-			<uni-search-bar
-        v-model="params.content"
-        radius="5"
-        placeholder="职位/酒店品牌/工作城市"
-        cancelButton="none"
-				bgColor="#fff"
-        :focus="false"
-				@clear="handleSearch('content', null)"
-        @confirm="handleSearch('content', params.content)"
-      ></uni-search-bar>
-			<view style="padding: 0 10px;">
-				<FilterList :list="filterList" idValue="label" @change="handleSearch"></FilterList>
-			</view>
-		</view>
-		
-		<scroll-view class="scrollBox" :scroll-y="true" @scrolltolower="loadingMore" style="position:relative;">
-			<TalentItem v-if="items?.length" :items="items" :showLastWorkExp="false" />
-			<uni-load-more v-if="more" :status="more" />
-			<view v-else class="noJobId">请选择条件搜索人才</view>
-		</scroll-view>
-	</view>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import TalentItem from './talentItem.vue'
-import FilterList from '@/components/FilterList'
-import { getPersonConditionSearchPage } from '@/api/search'
-import { dealDictArrayData } from '@/utils/position'
-import { timesTampChange, getTimeDifferenceInChinese } from '@/utils/date'
-
-// defineProps({ navbarHeight: [Number, String] })
-
-const query = ref({
-	pageNo: 1,
-	pageSize: 10
-})
-const params = ref({
-  content: null,
-  positionIds: [],
-  areaIds: [],
-  expType: '',
-  eduType: ''
-})
-const items = ref([])
-const more = ref('') // 没有筛选条件默认为空,展示提示语。
-const total = ref(0)
-const filterList = ref([
-  { label: '意向职位', dictType: 'positionTreeData',key: 'positionId', map: { text: 'nameCn', value: 'id' } },
-  { label: '意向城市', multiple: true, dictType: 'areaTreeData', key: 'workAreaIds', map: { text: 'name', value: 'id' } },
-  { label: '最高学历', dictType: 'menduner_education_type', key: 'eduType' },
-  { label: '工作经验', dictType: 'menduner_exp_type', key: 'expType' },
-])
-
-// 根据条件搜索人才
-const getTalentList = async () => {
-  try {
-		more.value = 'loading'
-		const { data } = await getPersonConditionSearchPage(Object.assign(query.value, params.value))
-
-		if (!data.list.length) {
-			more.value = 'noMore'
-			items.value = []
-			total.value = 0
-			return
-		}
-
-		const list = dealDictArrayData([], data.list).map(e => {
-      if (e.workList?.length) {
-        e.workList.forEach(exp => {
-          exp.startTimeStr = exp.startTime ? timesTampChange(exp.startTime, 'Y-M') : '未填写工作时间'
-          exp.endTimeStr = exp.startTime ? exp.endTime ? timesTampChange(exp.endTime, 'Y-M') : '至今' : ''
-          exp.year = exp.endTimeStr ? getTimeDifferenceInChinese(exp.startTime, exp.endTime) : ''
-        })
-				// e.workList = e.workList.splice(0, 2)
-      }
-      return e
-    })
-		items.value = items.value.concat(list)
-		total.value = data.total
-
-		if (items.value.length === +data.total) {
-      more.value = 'noMore'
-      return
-    }
-	} catch {
-		query.value.pageNo--
-		more.value = 'more'
-	}
-}
-
-const checkValue = (obj) => {
-  return Object.values(obj).some(value => {  
-    return value !== null && value !== undefined && value !== '' && (Array.isArray(value) ? value.length > 0 : true)
-  })
-}
-
-const handleSearch = (key, value) => {
-	query.value.pageNo = 1
-	params.value[key] = value
-
-	if (!checkValue(params.value)) {
-		uni.showToast({
-			title: '请至少选择一个查询条件',
-			icon: 'none',
-			duration: 2000
-		})
-		more.value = ''
-		items.value = []
-		total.value = 0
-		return
-	}
-
-	items.value = []
-	total.value = 0
-	getTalentList()
-}
-
-// 加载更多
-const loadingMore = () => {
-	if (more.value === 'noMore') return
-
-  more.value = 'loading'
-  query.value.pageNo++
-	getTalentList()
-}
-</script>
-
-<style scoped lang="scss">
-.noJobId {
-	text-align: center;
-	line-height: 60vh;
-	color: #666;
-}
-.box {
-  height: 100vh;
-  overflow: hidden;
-  box-sizing: border-box;
-  display: flex;
-  flex-direction: column;
-}
-.scrollBox{
-	flex: 1;
-  padding-bottom: 100px;
-  box-sizing: border-box;
-	height: 0 !important;
-}
-// .stick {
-//   z-index: 1;
-//   position: sticky;
-//   background-color: #fff;
-// }
-</style>

+ 0 - 115
pages/index/components/recommend.vue

@@ -1,115 +0,0 @@
-<template>
-	<view class="box defaultBgc">
-		<view style="padding: 10px">
-			<uni-data-select 
-				v-model="query.jobId" 
-				:clear="false" 
-				:localdata="jobList" 
-				@change="handleChangeJob" 
-				placeholder="招聘中职位"
-			></uni-data-select>
-		</view>
-		
-		<scroll-view class="scrollBox" :scroll-y="true" @scrolltolower="loadingMore" style="position:relative;">
-			<TalentItem v-if="items?.length || more !== 'loading'" :items="items" />
-			<uni-load-more v-if="items?.length" :status="more" />
-			<view v-if="!jobList?.length" class="noJobId text-center">暂无正在招聘中的职位</view>
-			<view v-if="jobList?.length && !items?.length" class="noJobId">
-				<view>请先选择上方正在招聘的职位</view>
-				<view>我们将根据您选择的职位为您推荐合适的人才</view>
-			</view>
-		</scroll-view>
-	</view>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import TalentItem from './talentItem.vue'
-import { getPersonRecommendPage } from '@/api/search'
-import { dealDictArrayData } from '@/utils/position'
-
-defineProps({ jobList: Array, navbarHeight: [Number, String] })
-
-const query = ref({
-	pageNo: 1,
-	paeSize: 20,
-	jobId: null
-})
-const items = ref([])
-const more = ref('noMore')
-const total = ref(0)
-
-// 根据职位id获取推荐人才列表
-const getRecommendList = async () => {
-  try {
-		more.value = 'loading'
-		const { data } = await getPersonRecommendPage(query.value)
-
-		if (!data.list.length) {
-			more.value = 'noMore'
-			return
-		}
-
-		const list = dealDictArrayData([], data.list)
-		items.value = items.value.concat(list)
-		total.value = data.total
-
-		if (items.value.length === +data.total) {
-      more.value = 'noMore'
-      return
-    }
-	} catch {
-		query.value.pageNo--
-		more.value = 'more'
-	}
-}
-getRecommendList()
-
-// 选择招聘中职位
-const handleChangeJob = () => {
-	query.value.pageNo = 1
-	items.value = []
-	total.value = 0
-	getRecommendList()
-}
-
-// 加载更多
-const loadingMore = () => {
-	if (more.value === 'noMore') return
-  more.value = 'loading'
-  query.value.pageNo++
-	getRecommendList()
-}
-</script>
-
-<style scoped lang="scss">
-.noJobId {
-	display: flex;
-	flex-direction: column;
-	margin-top: 26vh;
-	color: #666;
-	padding: 0 30rpx;
-	view {
-		text-align: center;
-		margin-top: 4px;
-	}
-}
-.box {
-  height: 100vh;
-  overflow: hidden;
-  box-sizing: border-box;
-  display: flex;
-  flex-direction: column;
-}
-.scrollBox{
-	flex: 1;
-  padding-bottom: 100px;
-  box-sizing: border-box;
-	height: 0 !important;
-}
-// .stick {
-//   z-index: 1;
-//   position: sticky;
-//   background-color: #fff;
-// }
-</style>

+ 0 - 144
pages/index/components/talentItem.vue

@@ -1,144 +0,0 @@
-<template>
-	<view>
-		<view v-for="(val, index) in items" :key="index" class="list-item" @tap.stop="handleDetail(val)" >
-			<!-- 基本信息 -->
-			<view class="d-flex align-center">
-				<view class="user-avatar">
-					<image class="user-avatar-img" :src="getUserAvatar(val.avatar, val.sex)" mode="scaleToFill"></image>
-					<image class="user-avatar-sex" :src="val?.sex ? val?.sex === '1' ? '/static/img/man.png' : '/static/img/female.png' : ''" alt="" mode="scaleToFill" />
-				</view>
-				<view style="flex: 1; margin-left: 10px;">
-					<view class="font-size-18" style="color: #0E100F">{{ val.name }}</view>
-					<view class="ss-m-t-10">
-						<span 
-							class="color-666 font-size-14"
-							v-for="(key, index) in desc" 
-							:key="index"
-						>
-							{{ val[key] }}
-							<span v-if="index !== desc.length - 1 && val[key]" class="ss-m-x-10">|</span>
-						</span>
-					</view>
-				</view>
-			</view>
-			
-			<!-- 感兴趣职位 -->
-			<view v-if="val.position?.positionNames && showLastWorkExp" class="ss-m-t-15 color-666 font-size-14">
-				意向职位:{{ val.position?.positionNames || '暂无' }}
-			</view>
-
-			<!-- 最近一份工作经验 -->
-			<view v-if="val?.lastWorkExp && showLastWorkExp" class="ss-m-t-15 color-666  font-size-14">
-				<view>
-					<uni-icons type="smallcircle" class="ss-m-r-10" color="#666"></uni-icons>
-					{{ formatName(val.lastWorkExp.enterpriseName) || '未填写企业名称' }}
-				</view>
-				<view class="ss-m-l-45">
-					<span>{{ formatName(val.lastWorkExp.positionName) || '未填写职位名称' }}</span>
-					<span v-if="val.lastWorkExp.startTime" class="ss-m-l-20">
-						{{ val.lastWorkExp.startTime ? timesTampChange(val.lastWorkExp.startTime, 'Y-M') : '暂无' }}
-						- 
-						{{ val.lastWorkExp.endTime ? timesTampChange(val.lastWorkExp.endTime, 'Y-M') : val.lastWorkExp.startTime ? '至今' : '' }}
-					</span>
-				</view>
-			</view>
-
-			<!-- 工作经历 -->
-			<view v-if="val?.workList && val.workList.length > 0 && !showLastWorkExp" class="ss-m-t-15 color-666 font-size-14">
-				<view v-for="(k, index) in val.workList" :key="k.id" class="ss-m-b-30">
-					<template v-if="val.showAll || index < 2">
-						<view>
-							<uni-icons type="smallcircle" class="ss-m-r-10" color="#666"></uni-icons>
-							{{ formatName(k.enterpriseName) || '未填写企业名称' }}
-						</view>
-						<view class="ss-m-l-45">
-							<span>{{ formatName(k.positionName) || '未填写职位名称' }}</span>
-							<span class="ss-m-l-20">
-								<span>{{ k.startTimeStr }}</span>
-								<span v-if="k.endTimeStr"> - {{ k.endTimeStr }}</span>
-							</span>
-						</view>
-					</template>
-				</view>
-				<view v-if="val.workList.length > 2" class="showBtn color-primary" @tap.stop="val.showAll = Boolean(!val.showAll)">
-					{{ val.showAll ? '收起' : '展开全部' }}
-					<view class="icons">
-						<uni-icons class="icon" :type="val.showAll ? 'up' : 'down'" color="#008BB7" size="12" />
-						<uni-icons class="icon" :type="val.showAll ? 'up' : 'down'" color="#008BB7" size="12" />
-					</view>
-				</view>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script setup>
-import { getUserAvatar } from '@/utils/avatar.js'
-import { timesTampChange } from '@/utils/date'
-import { formatName } from '@/utils/getText'
-
-defineProps({
-	items: Array,
-	showLastWorkExp: {
-		type: Boolean,
-		default: true
-	}
-})
-
-const desc = ['jobStatusName', 'eduName', 'expName']
-
-const handleDetail = ({ userId }) => {
-	if (!userId) {
-		uni.showToast({
-			title: '资源获取失败,请稍后重试',
-			icon: 'none',
-			duration: 2000
-		})
-		return
-	}
-	uni.navigateTo({
-		url: `/pagesB/personnelDetails/index?id=${userId}&type=1`
-	})
-}
-</script>
-
-<style scoped lang="scss">
-	.list-item {
-	  margin: 30rpx;
-	  border-radius: 20rpx;
-	  padding: 30rpx;
-	  background-color: #fbfbfb;
-	  box-shadow: 1px 2px 12px rgba(0, 0, 0, 0.17);
-	  border: 1rpx solid #E1E4E9;
-	}
-.user-avatar {
-	position: relative;
-	&-img {
-		width: 60px;
-		height: 60px;
-		border-radius: 50%;
-	}
-	&-sex {
-		position: absolute;
-		right: 0;
-		bottom: 2px;
-		width: 20px;
-		height: 20px;
-		background-color: #fff;
-		border-radius: 50%;
-	}
-}
-.showBtn {
-	display: flex;
-	justify-content: center;
-	align-items: center;
-	.icons {
-		display: flex;
-		flex-direction: column;
-		margin-left: 5px;
-		.icon {
-			line-height: 4px;
-		}
-	}
-}
-</style>

+ 0 - 199
pages/index/jobFair.vue

@@ -1,199 +0,0 @@
-<template>
-	<view>
-    <Navbar title="招聘会" />
-    <layout-page>
-      <view class="defaultBgc" style="padding-bottom: 100px;" :style="{'height': `calc(100vh - ${(navbarHeight + 100)}px)`, 'padding-top': navbarHeight + 'px'}">
-        <view v-if="items.length">
-          <view class="commonBackground"></view>
-          <scroll-view class="scrollBox" :scroll-y="true" @scrolltolower="loadingMore" style="position:relative;">
-            <view v-for="val in items" :key="val.id" @tap="handleToJobFairEnterprises(val)" class="list-item default-border">
-              <image v-if="val?.previewImg" class="ss-m-t-10" :src="val.previewImg" mode="widthFix" style="width: 100%; height: auto; border-radius: 6px;"></image>
-			        <view class="ss-m-t-20">活动主题:{{ val.title }}</view>
-              <view class="ss-m-t-20 ss-m-b-10">
-                活动状态:
-                <span class="font-weight-bold" :style="{'color': val.status === '0' ? '#00b760' : '#ff5252'}">
-                  {{ val.status === '0' ? checkActivityTime(val.startTime, val.endTime) ? '筹备中' : '进行中' : '已结束' }}
-                </span>
-              </view>
-              <view>活动时间:{{ timesTampChange(val.startTime, 'Y-M-D') }}至{{ timesTampChange(val.endTime, 'Y-M-D') }}</view>
-              <button class="ss-m-t-20 ss-m-b-10" style="background-color: #00B760; color: #fff;" type="primary">
-                {{ val.status === '0' ? '立即加入' : '查看详情' }}
-              </button>
-            </view>
-            <uni-load-more :status="more" />
-          </scroll-view>
-        </view>
-        <view v-else>
-          <view class="commonBackground"></view>
-          <view class="nodata-img-parent" :style="{'height': `calc(100vh - ${(navbarHeight + 100)}px)`}">
-            <image src="https://minio.menduner.com/dev/bb43df1dc91945e05ee93da76e49b34f87b0d10203eb76c20e2d4999a13b9a0a.png" mode="widthFix" style="width: 100vw;height: 100vh;"></image>
-          </view>
-        </view>
-      </view>
-
-      <payPopup ref="payRef" @paySuccess="paySuccess"></payPopup>
-    </layout-page>
-  </view>
-</template>
-
-<script setup>
-import { ref, watch } from 'vue'
-import layoutPage from '@/layout'
-import Navbar from '@/components/Navbar'
-import { onShow } from '@dcloudio/uni-app'
-import { getAccessToken } from '@/utils/request'
-import { showAuthModal } from '@/hooks/useModal'
-import { getJobFairList, checkJobFairPermission } from '@/api/jobFair'
-import { timesTampChange } from '@/utils/date'
-import { userStore } from '@/store/user'
-import payPopup from '@/components/payPopup'
-
-const useUserStore = userStore()
-const items = ref([])
-const navbarHeight = ref(uni.getStorageSync('navbarHeight'))
-const total = ref(0)
-const query = ref({
-	pageNo: 1,
-	pageSize: 20
-})
-const more = ref('more')
-
-// 获得招聘会列表
-const getList = async () => {
-	if (query.value.pageNo < 1) return
-	if (query.value.pageNo === 1) items.value = []
-  try {
-	  more.value = 'loading'
-	  uni.showLoading({ title: '加载中' })
-    const res = await getJobFairList(query.value)
-    const list = res?.data?.list || []
-    if (!list?.length) {
-      more.value = 'noMore'
-      return
-    }
-    items.value = items.value.concat(...list)
-    total.value = res.data.total
-    more.value = 'more'
-    if (items.value.length === +total.value) {
-      more.value = 'noMore'
-      return
-    }
-  } catch (error) {
-	  query.value.pageNo--
-	  more.value = 'more'
-  } finally {
-    uni.hideLoading()
-  }
-}
-
-function checkActivityTime(startTimeStamp) {
-  const now = new Date()
-  const currentTime = now.getTime()
- 
-  const startDate = new Date(startTimeStamp)
-  const startOfDay = new Date(
-    startDate.getFullYear(),
-    startDate.getMonth(),
-    startDate.getDate(),
-    0, 0, 0, 0
-  )
-  const adjustedStartTime = startOfDay.getTime()
- 
-  // 判断时间关系
-  if (currentTime < adjustedStartTime) return true // 活动未开始
-}
-
-// 加载更多
-const loadingMore = () => {
-  if (more.value === 'noMore') return
-
-  more.value = 'loading'
-  query.value.pageNo++
-  getList()
-}
-
-watch(() => useUserStore.refreshToken, () => {
-	if (!useUserStore.refreshToken) return items.value = []
-	getList()
-})
-
-onShow(() => {
-	// 设置自定义tabbar选中值
-  const currentPage = getCurrentPages()[0]  // 获取当前页面实例
-  const currentTabBar = currentPage?.getTabBar?.()
-
-  // 设置当前tab页的下标index
-  currentTabBar?.setData({ selected: 3 })
-
-	if (!getAccessToken()) return showAuthModal()
-
-  getList()
-})
-
-//跳转招聘会详情
-const payRef = ref()
-const itemData = ref({})
-const handleToJobFairEnterprises = async (val) => {
-  itemData.value = val
-  if (!val?.id) {
-    uni.showToast({ title: '资源获取失败,请稍后重试', icon: 'none' })
-  }
-  uni.showLoading({ title: '加载中' })
-
-  try {
-    const { data } = await checkJobFairPermission(val.id)
-    uni.hideLoading()
-    if (data) {
-      uni.navigateTo({
-        url: '/pagesB/jobFair/details?id=' + val.id
-      })
-    }
-  } catch (error) {
-    uni.hideLoading()
-    // 权限被禁用
-    if (error?.code === 1100056008) {
-      uni.showToast({ title: error.msg, icon: 'none', duration: 2000 })
-      return
-    }
-    // 没有权限参加招聘会,购买门票
-    if (error?.code === 1100056005) {
-      // 没有设置门票金额则提示无权限参加
-      if (!val?.admissionPrice || val?.admissionPrice <= 0) {
-		    const title = val?.status === '1' ? '您没有参加该招聘会,暂无详情查看' : error.msg
-        uni.showToast({ title, icon: 'none', duration: 2000 })
-        return
-      }
-      // 设置门票金额则提示购买门票
-      uni.showToast({ title: '您暂时无法参加该招聘会,请先购买门票', icon: 'none', duration: 2000 })
-
-      payRef.value && payRef.value.handleOpen({ spuId: val?.id || '', spuName: val?.title || '', price: val.admissionPrice, type: 5 })
-    }
-  }
-}
-
-// 支付成功
-const paySuccess = () => {
-  uni.showToast({ title: '支付成功', icon: 'success', duration: 2000 })
-  handleToJobFairEnterprises(itemData.value)
-}
-</script>
-
-<style scoped lang="scss">
-.scrollBox {
-	height: 100vh;
-	box-sizing: border-box;
-	padding-bottom: 100px;
-}
-.list-item {
-  margin: 0 30rpx 30rpx 30rpx;
-  border-radius: 20rpx;
-  padding: 30rpx;
-  position: relative;
-  background-color: #fbfbfb;
-  box-shadow: 1px 2px 12px rgba(0, 0, 0, 0.17);
-  view {
-    font-size: 28rpx;
-    color: #666;
-  }
-}
-</style>

+ 0 - 56
pages/index/loading.vue

@@ -1,56 +0,0 @@
-<template>
-  <view class="box">
-    <image class="img" src="https://minio.menduner.com/dev/fe9890be9b1176f84f2aa282b0f6adce300b133f65eb3d7b45ae057aa5698324.png"></image>
-    <view class="color-primary font-size-20 font-weight-bold">门墩儿 专注顶尖招聘</view>
-    <view class="icons">
-      <uni-icons type="spinner-cycle" size="24" />
-    </view>
-  </view>
-</template>
-
-<script setup>
-import { onShow } from '@dcloudio/uni-app'
-import { getAccessToken } from '@/utils/request'
-import { showAuthModal } from '@/hooks/useModal'
-import { userStore } from '@/store/user'
-const useUserStore = userStore()
-
-const tabBarControl = (show = false) => { // 显示/隐藏 TabBar
-  const currentPage = getCurrentPages()
-  if (!currentPage) return
-  const currentTabBar = currentPage[0]?.getTabBar?.()
-  currentTabBar?.setData({ show })
-}
-
-onShow(async() => {
-  tabBarControl(false) // 隐藏页面底部导航
-  
-  // 检查是否是个人令牌
-  if (getAccessToken() && uni.getStorageSync('isPersonalToken')) {
-    // 查看用户是否有在申请中的数据
-    const { code } = await useUserStore.getPersonalApplyingData()
-    uni.redirectTo({ url: code ? '/pages/register/review?hasData=true' : '/pages/register/index' })
-    return
-  }
-
-	if (!getAccessToken()) showAuthModal()
-  uni.reLaunch({ url: '/pages/index/search' }) // 进入门墩儿
-})
-</script>
-<style lang="scss" scoped>
-.box {
-  text-align: center;
-  .img {
-    width: 105px;
-    height: 45px;
-    margin-top: 30vh;
-    margin-bottom: 16px;
-  }
-  .icons {
-    position: fixed;
-    bottom: 20vh;
-    width: 100%;
-    margin: 0 auto;
-  }
-}
-</style>

+ 0 - 236
pages/index/my.vue

@@ -1,236 +0,0 @@
-<template>
-  <view>
-		<Navbar title="我的" />
-		<layout-page>
-			<view :style="{'padding-top': navbarHeight + 'px'}">
-				<view class="commonBackground"></view>
-				<view class="pb-150 defaultBgc">
-					<view class="text-center ss-p-b-30" :class="vip ? 'vipBox' : 'avatarBox'" @tap="handleLogin" style="position: relative;">
-						<img :src="getUserAvatar(userInfo?.avatar, userInfo?.sex)" alt="" class="img-box">
-						<image v-if="vip" src="/static/svg/vip.svg" class="vipIcon"></image>
-						<view v-if="!useUserStore.isLogin" class="font-weight-bold font-size-20">点击登录</view>
-						<view v-else class="ss-m-t-30">
-							<view>
-								<span class="font-weight-bold font-size-20">{{ userInfo?.name || userInfo?.phone }}</span>
-								<uni-icons @tap="handleEdit('/pagesB/staffInfoEdit/index')" class="ss-m-l-10" type="compose" :size="22"></uni-icons>
-							</view>
-							<view style="color: #0E100F" class="ss-m-t-20">
-								<span>{{ formatName(userInfo?.enterpriseAnotherName || userInfo?.enterpriseName) }}</span>
-								<uni-icons @tap="handleEdit('/pagesB/companyInfoEdit/index')" class="ss-m-l-10" type="compose" :size="22"></uni-icons>
-							</view>
-						</view>
-					</view>
-
-					<view class="defaultBgc ss-p-t-30">
-						<view class="list-card">
-							<uni-list>
-								<uni-list-item
-									v-for="item in list"
-									:clickable="true"
-									:key="item.title"
-									:title="item.title"
-									showArrow
-									:rightText="item.rightTex || ''"
-									@click="handleToLink(item)"
-								>
-								</uni-list-item>
-							</uni-list>
-						</view>
-				
-						<button v-if="useUserStore.isLogin" class="send-button" style="margin-bottom: 50px;" @tap="handleLogout">退出登录</button>
-					</view>
-			
-					<uni-popup ref="popup" type="dialog">
-						<uni-popup-dialog type="warn" cancelText="取消" confirmText="确定" title="系统提示" content="确认退出账号?" @confirm="handleLogoutConfirm"
-							@close="handleLogoutClose"></uni-popup-dialog>
-					</uni-popup>
-
-					<uni-popup ref="inputDialog" type="dialog">
-						<view class="shareQrCodePopupContent">
-							<view>请前往网页版{{ dialogType ? '门墩儿招聘' : '门墩儿商城' }}</view>
-							<uni-link class="ss-m-t-10" :href="dialogType ? 'https://www.menduner.com' : 'https://www.menduner.com/mall'" text="点击复制网页地址" color="#00B760" fontSize="16" copyTips="已复制,请在电脑端打开"></uni-link>
-						</view>
-					</uni-popup>
-				</view>
-			</view>
-		</layout-page>
-	</view>
-</template>
-
-<script setup>
-import { ref, computed, watch } from 'vue'
-import { userStore } from '@/store/user'
-import { getUserAvatar } from '@/utils/avatar'
-import { getAccessToken } from '@/utils/request'
-import layoutPage from '@/layout'
-import { formatName } from '@/utils/getText'
-import { showAuthModal } from '@/hooks/useModal'
-import { onShow, onLoad, onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
-import Navbar from '@/components/Navbar'
-
-const navbarHeight = ref(uni.getStorageSync('navbarHeight'))
-
-// 设置自定义tabbar选中值
-onShow(() => {
-    const currentPage = getCurrentPages()[0];  // 获取当前页面实例
-    const currentTabBar = currentPage?.getTabBar?.();
-
-    // 设置当前tab页的下标index
-    currentTabBar?.setData({ selected: 4 });
-})
-
-const inputDialog = ref()
-const useUserStore = userStore()
-const userInfo = computed(() => useUserStore?.userInfo)
-
-const vip = computed(() => new Date().getTime() < useUserStore?.userInfo?.vipExpireDate)
-
-const popup = ref()
-
-const defaultList = [
-	{ title: '简历管理', path: '/pagesA/resume/index' },
-	{ title: '面试管理', path: '/pagesA/interview/index' },
-	{ title: '修改密码', path: '/pagesA/editPassword/index' },
-	{ title: '联系我们', path: '/pagesB/contactUs/index' },
-	{ title: '协议中心', path: '/pagesB/agreement/index', open: true },
-	{ title: '我要求职', appId: 'wx5dd538ccc752b03a' },
-]
-const list = ref(defaultList.filter(e => !e.defaultHide))
-
-onLoad(() => {
-  wx.showShareMenu({
-    withShareTicket: true,
-    menus: ['shareAppMessage', 'shareTimeline']
-  })
-  onShareAppMessage(() => {
-    return {
-      title: '门墩儿 专注顶尖招聘',
-      path: '/pages/index/position',
-			imageUrl: '../../static/img/share-poster.jpg'
-    }
-  })
-	onShareTimeline(() => {
-    return {
-      title: '门墩儿 专注顶尖招聘',
-      path: '/pages/index/position',
-			imageUrl: '../../static/img/share-poster.jpg'
-    }
-  })
-})
-
-// 列表跳转
-const dialogType = ref('')
-const handleToLink = (item) => {
-	if (item.open && item.path) return uni.navigateTo({ url: item.path })
-	if (item.appId) {
-		uni.navigateToMiniProgram({
-			appId: item.appId,
-		})
-		return
-	}
-	if (item?.showDialog) {
-		dialogType.value = 0
-		inputDialog.value.open()
-		return
-	}
-	if (!item.path) return
-  if (!getAccessToken()) {
-		uni.showToast({
-			title: '请先登录',
-			icon: 'none'
-		})
-		showAuthModal()
-		return
-	}
-	uni.navigateTo({
-		url: item.path
-	})
-}
-
-const handleEdit = (url) => {
-	if (!useUserStore.isLogin) {
-		showAuthModal()
-		return
-	}
-	if (!url) return
-	uni.navigateTo({
-		url
-	})
-}
-
-// 退出登录
-const handleLogout = () => {
-  popup.value.open()
-}
-const handleLogoutClose = () => {
-  popup.value.close()
-}
-const handleLogoutConfirm = () => {
-	// list.value = defaultList.filter(e => !e.hide) // 重置菜单
-  useUserStore.handleLogout()
-}
-const handleLogin = () => {
-  if (!getAccessToken()) {
-		showAuthModal()
-	}
-}
-</script>
-
-<style scoped lang="scss">
-.list-card {
-	margin: 0 30rpx 30rpx 30rpx;
-	border-radius: 20rpx;
-	overflow: hidden;
-}
-.pb-150 {
-	padding-bottom: 100px;
-}
-.img-box {
-  width: 150rpx;
-  height: 150rpx;
-  border: 2rpx solid #ccc;
-  border-radius: 50%;
-}
-.vipBox {
-	color: #a18a0f;
-	.img-box {
-    border: 1px solid gold;
-	}
-	.vipIcon {
-		position: absolute;
-		width: 45px;
-		height: 24px;
-		top: 60px;
-		left: 50%;
-	}
-}
-:deep(.uni-list-item) {
-	height: 120rpx !important;
-	line-height: 120rpx !important;
-}
-:deep(.uni-list-item__content-title) {
-	font-size: 28rpx !important;
-}
-
-:deep(.uniui-arrowright) {
-	color: #0E100F !important;
-}
-.shareQrCodePopupContent {
-	width: 75vw;
-	padding: 40rpx;
-	margin-bottom: 20rpx;
-	text-align: center;
-	background-color: #fff;
-	.text {
-		margin-bottom: 20px;
-	}
-	.qrCode {
-		margin-left: 4px;
-	}
-	.saveImg {
-		text-align: center;
-		margin-top: 10px;
-		color: #999;
-	}
-}
-</style>

+ 0 - 280
pages/index/position.vue

@@ -1,280 +0,0 @@
-<template>
-  <view>
-    <Navbar title="职位" />
-    <layout-page @loginSucceeded="init">
-      <view :style="{'padding-top': navbarHeight + 'px'}">
-        <view class="commonBackground"></view>
-        <view class="box defaultBgc">
-          <uni-segmented-control :current="tab" :values="controlList" @clickItem="tabChange" styleType="text" activeColor="#00B760"></uni-segmented-control>
-          <view class="stick" style="border-radius: 5px;">
-            <!-- 搜索条 -->
-            <uni-search-bar
-              v-model="query.name"
-              radius="5"
-              placeholder="输入关键字"
-              cancelButton="none"
-              bgColor="#fff"
-              :focus="false"
-              @confirm="onSearch"
-            ></uni-search-bar>
-            <!-- 可发布职位数 -->
-            <view class="publishJobCountBox">
-              <span>可发布职位数 <span class="color-primary">{{ publishJobCount }}</span> 个</span>
-            </view>
-          </view>
-          <scroll-view class="scrollBox" :scroll-y="true" @scrolltolower="loadingMore" style="position:relative;">
-            <view>
-              <view v-if="!positionListData?.length && more !== 'loading'" class="d-flex flex-column align-center justify-center ss-m-t-30">
-                <image src="https://minio.menduner.com/dev/bb43df1dc91945e05ee93da76e49b34f87b0d10203eb76c20e2d4999a13b9a0a.png" class="ss-m-t-20" mode="widthFix" style="width: 100vw"></image>
-                <view class="color-999">暂无职位</view>
-                <view class="f-horizon-center">
-                  <button type="primary" size="default" class="ss-m-t-50" style="width: 60vw;" @click="handleClickAdd">发布新职位</button>
-                </view>
-              </view>
-              <view v-else>
-                <PositionList v-if="positionListData?.length" :tab="tab" :jobNum="publishJobCount" :payable="true" :list="positionListData" :noMore="false" @refresh="refresh"></PositionList>
-                <uni-load-more :status="more" />
-                <view style="padding-bottom: 20vh;"></view>
-                <view class="addBtn" @tap="handleClickAdd">
-                  <view class="addBox">
-                    <view class="icon">+</view>
-                    <view class="text">发布新职位</view>
-                  </view>
-                </view>
-              </view>
-            </view>
-          </scroll-view>
-        </view>
-      </view>
-    </layout-page>
-  </view>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import layoutPage from '@/layout'
-import Navbar from '@/components/Navbar'
-import PositionList from '@/components/PositionList'
-import { dealDictArrayData } from '@/utils/position'
-import { getJobAdvertisedList } from '@/api/new/position'
-import { onShow, onLoad } from '@dcloudio/uni-app'
-import { getAccessToken } from '@/utils/request'
-import { showAuthModal } from '@/hooks/useModal'
-import { userStore } from '@/store/user'; const useUserStore = userStore()
-
-const tab = ref(1)
-const navbarHeight = ref(uni.getStorageSync('navbarHeight'))
-
-onLoad((options) => {
-  if (options?.tab) tab.value = Number(options?.tab)
-})
-
-const tabList = [
-  { label: '待发布', value: 0, status: 99 },
-  { label: '招聘中', value: 1, status: 0 },
-  { label: '已关闭', value: 2, status: 1 }
-]
-const controlList = tabList.map(e => e.label)
-
-const tabChange = (e) => {
-  tab.value = e.currentIndex
-  query.value.pageNo = 1
-  getData()
-}
-
-const total = ref(0)
-const positionListData = ref([])
-const query = ref({
-  pageSize: 10, 
-  pageNo: 1,
-  hire: false,
-  // jobFairId: 0,
-  name: '',
-})
-const more = ref('more')
-
-const getData = async () => {
-  if (query.value.pageNo < 1) return
-  if (query.value.pageNo === 1) positionListData.value = []
-  try {
-    more.value = 'loading'
-    query.value.status = tabList[tab.value].status
-    const res = await getJobAdvertisedList(query.value)
-    const list = res?.data?.list?.length ? res.data.list : []
-    total.value = res.data.total-0
-    if (!list?.length) {
-      more.value = 'noMore'
-      return
-    }
-    positionListData.value.push(...dealDictArrayData([], list))
-    more.value = 'more'
-    if (positionListData.value.length === total.value) {
-      more.value = 'noMore'
-      return
-    }
-  } catch (error) {
-    query.value.pageNo--
-    more.value = 'more'
-  }
-}
-
-// 设置自定义tabbar选中值
-onShow(() => {
-  const currentPage = getCurrentPages()[0] // 获取当前页面实例
-  const currentTabBar = currentPage?.getTabBar?.()
-
-  // 设置当前tab页的下标index
-  currentTabBar?.setData({ selected: 1 })
-  init()
-  // 延迟查询可发布职位数量
-  setTimeout(() => {
-    getPublishJobCount()
-  }, 1000)
-})
-
-const publishJobCount = ref(0)
-const getPublishJobCount = async () => {
-  const info = await useUserStore.getUserInfos()
-  publishJobCount.value = info?.entitlement?.publishJobCount - 0 || 0
-}
-
-const init = () => {
-  query.value.pageNo = 1
-  getData()
-}
-
-const onSearch = () => {
-  query.value.pageNo = 1
-  getData()
-}
-
-// 加载更多
-const loadingMore = () => {
-  if (more.value === 'noMore') return
-
-  more.value = 'loading'
-  query.value.pageNo++
-  getData()
-}
-
-// reset: 刷新列表
-const refresh = async ({ reset = false }) => {
-  if (reset) query.value.pageNo = 1
-  getData()
-}
-
-const handleClickAdd = () => {
-  if (!getAccessToken()) {
-		uni.showToast({
-			title: '请先登录',
-			icon: 'none'
-		})
-		showAuthModal()
-		return
-	}
-  uni.navigateTo({ url: '/pagesB/positionAdd/select' })
-}
-
-</script>
-
-<style scoped lang="scss">
-.stick {
-  z-index: 1;
-  position: sticky;
-  top: 0;
-}
-.stickFilter {
-  z-index: 1;
-  position: sticky;
-  box-shadow: 0px 10rpx 12rpx 0px rgba(195, 195, 195, .25);
-  top: 110rpx;
-}
-.px-0 { padding-left: 0 !important; padding-right: 0 !important; }
-.pb-10 {
-  padding-bottom: 10px;
-}
-.pb-20 { padding-bottom: 20px; }
-.px-5 { padding-left: 5px; padding-right: 5px; }
-.px-10 { padding-left: 10px; padding-right: 10px; }
-.mx-10 { margin-left: 10px; margin-right: 10px }
-.mx-20 { margin-left: 20px; margin-right: 20px; }
-.mb-10 { margin-bottom: 10px; }
-.box {
-  height: 100vh;
-  overflow: hidden;
-  box-sizing: border-box;
-  display: flex;
-  flex-direction: column;
-}
-.scrollBox{
-  flex: 1;
-  height: 0 !important;
-  padding-bottom: 24rpx;
-  box-sizing: border-box;
-}
-
-.stickBtn{
-  text-align: center;
-  width: calc(50% - 2px);
-  height: 24px;
-  line-height: 24px;
-  margin: 8px 0;
-  color: grey;
-  font-size: 13px;
-}
-
-.newPositionBtn{
-  color: #00B760;
-  border-left: 1px solid #c3c3c3;
-}
-
-.actColor{
-  color: #00B760;
-}
-
-.addBtn{
-  position: fixed;
-  margin-bottom: 20px;
-  right: 35rpx;
-  // left: 50%;
-  // transform: translateX(-50%);
-  bottom: calc(env(safe-area-inset-bottom) + 60px);
-  width: 70px;
-  .addBox {
-    position: relative;
-    .icon {
-      font-size: 42px;
-      color: #fff;
-      background-color: #00B760;
-      width: 50px;
-      height: 50px;
-      line-height: 46px;
-      text-align: center;
-      border-radius: 50%;
-      margin: 0 auto;
-      box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3);
-    }
-    .text {
-      position: absolute;
-      top: 42px;
-      font-size: 12px;
-      color: #00B760;
-      background-color: #ffffffc9;
-      text-align: center;
-      padding: 2px 4px;
-      margin: 0 auto;
-      border-radius: 6px;
-      box-shadow: 0 36px 6px rgba(0, 0, 0, 0.1);
-    }
-  }
-}
-.publishJobCountBox {
-  font-size: 12px;
-  margin-left: 30rpx;
-  color: #666;
-  padding-bottom: 10px;
-  .color-primary {
-    font-weight: bold;
-  }
-}
-</style>

+ 0 - 131
pages/index/search.vue

@@ -1,131 +0,0 @@
-<template>
-	<view>
-		<Navbar :showLogo="true" />
-		<layout-page>
-			<view :style="{'padding-top': navbarHeight + 'px'}">
-				<view class="commonBackground"></view>
-				<view class="box defaultBgc">
-          <!-- <SwiperAd v-if="swiperAdList?.length" margin="0 10px 10px 10px" :list="swiperAdList" imgUrlKey="img" :strType="false" /> -->
-					<view>
-						<uni-segmented-control 
-							:current="current"
-							:values="tabList"
-							@clickItem="changeControl"
-							styleType="text"
-							activeColor="#00B760"
-						></uni-segmented-control>
-					</view>
-
-					<!-- 职位推荐 -->
-					<RecommendPage v-if="current === 0" :jobList="jobList" :navbarHeight="navbarHeight" />
-
-					<!-- 条件筛选 -->
-					<ConditionPage v-else :navbarHeight="navbarHeight" />
-				</view>
-			</view>
-		</layout-page>
-	</view>
-</template>
-
-<script setup>
-import { ref, watch, onMounted } from 'vue'
-import { onShow } from '@dcloudio/uni-app'
-import layoutPage from '@/layout'
-import Navbar from '@/components/Navbar'
-// import SwiperAd from '@/components/SwiperAd'
-import { getAccessToken } from '@/utils/request'
-import { showAuthModal } from '@/hooks/useModal'
-import { getJobAdvertised } from '@/api/search'
-import { userStore } from '@/store/user'
-import { formatName } from '@/utils/getText'
-import RecommendPage from './components/recommend.vue'
-import ConditionPage from './components/condition.vue'
-import { getWebContent } from '@/api/common'
-
-const navbarHeight = ref(0)
-
-onMounted(async () => {
-  try {
-    const res = await new Promise((resolve, reject) => {
-      uni.getStorage({
-        key: 'navbarHeight',
-        success: (result) => resolve(result),
-        fail: (err) => reject(err)
-      })
-    })
-    navbarHeight.value = res.data
-	  console.log(navbarHeight.value, '职位列表-导航栏高度')
-  } catch (error) {
-    console.error('读取本地缓存出错:', error)
-  }
-})
-
-const current = ref(0)
-const tabList = ['人才推荐', '条件筛选']
-const useUserStore = userStore()
-
-// 获取轮播图
-const swiperAdList = ref([])
-const getSystemWebContent = async () => {
-  const { data } = await getWebContent()
-  swiperAdList.value = data?.appHomeCarousel || []
-}
-
-// 职位列表
-const jobList = ref([])
-const getJobList = async () => {
-	if (!useUserStore.refreshToken || uni.getStorageSync('isPersonalToken')) {
-		return
-	}
-  const { data } = await getJobAdvertised({ status: 0, exTime: 0 })
-  if (data.length) {
-    jobList.value = data.map(e => {
-      return { text: `${formatName(e.name)}_${e.areaName ? e.area?.str : '全国'}`, value: e.id }
-    })
-  }
-}
-
-watch(() => useUserStore.refreshToken, () => {
-	getJobList()
-}, { immediate: true })
-
-onShow(() => {
-	// getSystemWebContent()
-
-	// 设置自定义tabbar选中值
-  const currentPage = getCurrentPages()[0]  // 获取当前页面实例
-  const currentTabBar = currentPage?.getTabBar?.()
-
-  // 设置当前tab页的下标index
-  currentTabBar?.setData({ selected: 0 })
-
-	if (!getAccessToken()) return showAuthModal()
-	else getJobList()
-})
-
-const changeControl = (e) =>{
-  current.value = e.currentIndex
-}
-</script>
-
-<style scoped lang="scss">
-:deep {
-	.uni-select__selector-item {
-		display: block !important;
-		text-align: left !important;
-		max-width: 100% !important;
-		white-space: nowrap !important;
-		text-overflow: ellipsis !important;
-		overflow: hidden !important;
-	}
-	.uni-select {
-		background-color: #fff !important;
-	}
-}
-// .stick {
-//   z-index: 1;
-//   position: sticky;
-//   background-color: #fff;
-// }
-
-</style>

+ 0 - 483
pages/index/welfare.vue

@@ -1,483 +0,0 @@
-<template>
-  <layout-page>
-		<view class="box defaultBgc">
-      <scroll-view class="scrollBox" scroll-y="true">
-        <view class="content">
-          <!-- 钱包 -->
-          <view class="wallet">
-            <view class="wallet-content">
-              <view class="wallet-content-member">
-                <view class="iconBox">
-                  <view class="iconBox-line">
-                    <uni-icons type="vip-filled" size="20" color="#ffbc00"></uni-icons>
-                  </view>
-                </view>
-                <view class="name">
-                  <text v-if="useUserStore.isLogin" @tap="toInfo" class="active">
-                    {{ useUserStore?.baseInfo?.name || useUserStore?.userInfo?.phone }}
-                  </text>
-                  <text v-else @tap="handleLogin">点击登录</text>
-                </view>
-                </view>
-              <view class="wallet-content-integral wallet-content-item" @tap="handleTo('integral')">
-                <text>{{ balance.point || 0 }}</text>
-                <text class="title">积分</text>
-              </view>
-              <view class="wallet-content-cash wallet-content-item" @tap="handleTo('balance')">
-                <text>{{ balance.balance > 0 ? (balance?.balance / 100.0).toFixed(2) : 0 }}</text>
-                <text class="title">余额</text>
-              </view>
-            </view>
-          </view>
-          <!-- 签到 -->
-          <!-- <view class="signIn">
-            <view class="signIn-content">
-              <view class="signIn-content-items">
-                <view class="item" v-for="(sign, i) in SignItems" :key="sign.day">
-                  <view class="box" :class="{ active: i < continuousDay }">
-                    <uni-icons type="vip" size="30" color="#ffbc00" style="text-align: center;"></uni-icons>
-                    <text class="text">+{{ sign.point }}</text>
-                  </view>
-                  <view class="day">
-                    <text>{{ i === todayNumber ? '今' : '第' + sign.day }}天</text>
-                  </view>
-                </view>
-              </view>
-              <view class="tips">
-                <button
-                  :disabled="todaySignIn"
-                  :class="{ disabled: todaySignIn }"
-                  @tap="handleSignIn"
-                >
-                  {{ todaySignIn ? '已签到' : '签到'}}
-                </button>
-              </view>
-            </view>
-          </view> -->
-          <!-- 积分规则、积分兑换 -->
-          <view class="ss-m-t-20">
-            <uni-section title="积分规则" type="line"  style="background-color: #fff;">
-              <uni-list>
-                <uni-list-item v-for="(k, i) in integralRules" :key="i" :showArrow="false">
-                  <template v-slot:header>
-                    <text class="ss-m-t-10">{{ k.title }}</text>
-                  </template>
-                  <template v-slot:footer>
-                    <view class="d-flex align-center" style="width: 130px; text-align: start; position: relative;">
-                      <image src="/static/svg/integral.svg" style="width: 30px; height: 30px;"></image>
-                      <view class="color-primary ss-m-l-10">{{ k.point }}</view>
-                      <uni-tag :inverted="true" :text="k.complete ? '已完成' : '未完成'" :type="k.complete ? 'success' : 'error'" style="position: absolute; right: 0;" />
-                    </view>
-                  </template>
-                </uni-list-item>
-              </uni-list>
-            </uni-section>
-            <view class="ss-m-t-20">
-              <uni-section title="积分兑换" type="line" style="background-color: #fff;">
-                <view class="goods" >
-                  <view class="goods-item" v-for="(item,index) in goodsList" :key="index" @tap.stop="handleClickGoods">
-                    <image :src="item.url" class="goods-item-img" mode="widthFix"></image>
-                    <view class="goods-item-name">{{ item.name }}</view>
-                    <view>消耗积分<text class="goods-item-price">{{ item.point }}</text></view>
-                  </view>
-                </view>
-              </uni-section>
-            </view>
-          </view>
-        </view>
-      </scroll-view>
-		</view>
-
-    <uni-popup ref="inputDialog" type="dialog">
-      <view class="shareQrCodePopupContent">
-        <view class="ss-m-b-10">请前往网页版门墩儿商城兑换</view>
-        <uni-link href="https://www.menduner.com/mall" text="点击复制网页地址" color="#00B760" fontSize="16" copyTips="已复制,请在电脑端打开"></uni-link>
-      </view>
-    </uni-popup>
-	</layout-page>
-</template>
-
-<script setup>
-import { ref, watch } from 'vue'
-import layoutPage from '@/layout'
-import {
-	// getRewardSignInConfigList,
-	// getRewardSignInRecordSummary,
-  // createRewardSignInRecord,
-  getAccountBalance,
-  getUserAccount,
-} from '@/api/sign'
-import { getTaskList } from '@/api/integral'
-import { onShow, onLoad, onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
-import { userStore } from '@/store/user'
-import { showAuthModal } from '@/hooks/useModal'
-import { showNecessaryInfoPopup } from '@/utils/request'
-
-const inputDialog = ref()
-const useUserStore = userStore()
-// 设置自定义tabBar选中值
-
-// const SignItems = ref([])
-// 积分规则
-const integralRules = ref([])
-const getTask = async () => {
-  const { data } = await getTaskList({ mark: '推荐任务', type: 0 })
-  integralRules.value = data
-}
-// 商品列表
-const goodsList = [
-  { name: '房券-高端酒店房券', point: 12000, url: 'https://minio.menduner.com/dev/menduner/hotalRoomVoucher.png' },
-  { name: '门墩儿酒店英语学习年卡', point: 8000, url: 'https://minio.menduner.com/dev/menduner/englishCourses.jpg' },
-  { name: '红酒-经典年份葡萄酒', point: 5000, url: 'https://minio.menduner.com/dev/menduner/redWine.png' },
-  { name: '瑞幸咖啡券-瑞幸咖啡精致享受券', point: 2000, url: 'https://minio.menduner.com/dev/menduner/coffee.png' },
-  { name: '减压捏捏乐', point: 500, url: 'https://minio.menduner.com/dev/menduner/pinchMusic.png' }
-]
-
-onLoad(() => {
-  wx.showShareMenu({
-    withShareTicket: true,
-    menus: ['shareAppMessage', 'shareTimeline']
-  })
-  onShareAppMessage(() => {
-    return {
-      title: '门墩儿 专注顶尖招聘',
-      path: '/pages/index/position',
-      imageUrl: '../../static/img/share-poster.jpg'
-    }
-  })
-  onShareTimeline(() => {
-    return {
-      title: '门墩儿 专注顶尖招聘',
-      path: '/pages/index/position',
-      imageUrl: '../../static/img/share-poster.jpg'
-    }
-  })
-})
-
-const handleClickGoods = () => {
-  // uni.showToast({
-  //   icon: 'none',
-  //   title: '请前往网页版门墩儿商城兑换'
-  // })
-  inputDialog.value.open()
-}
-
-// 连续签到天数
-// const continuousDay = ref(0)
-// 今天有无签到
-// const todaySignIn = ref(false)
-
-// 今天
-// const todayNumber = ref()
-
-const balance = ref({})
-
-watch([() => useUserStore.refreshToken, () => useUserStore.isLogin], () => {
-  if (useUserStore.isLogin) {
-    // getSummary()
-    getBalance()
-  }
-})
-
-onShow(() => {
-  const currentPage = getCurrentPages()[0];  // 获取当前页面实例
-  const currentTabBar = currentPage?.getTabBar?.();
-  // 设置当前tab页的下标index
-  currentTabBar?.setData({ selected: 2 });
-  init()
-})
-
-function init () {
-  // 获取签到列表
-  // getSignIn()
-  // 获取签到信息
-  // getSummary()
-  // 获取余额积分
-  getBalance()
-  // 获取积分规则列表
-  getTask()
-}
-
-// 获取积分余额
-async function getBalance() {
-  const { data } = await getAccountBalance()
-  const { data: _data } = await getUserAccount()
-  balance.value = {
-    ...data,
-    point: _data?.point
-  }
-}
-
-
-// 获取个人签到统计
-// async function getSummary() {
-//   const { data } = await getRewardSignInRecordSummary()
-//   if (!data) return
-//   continuousDay.value = data.continuousDay // 连续签到第n天
-//   todaySignIn.value = data.todaySignIn // 今天有无签到
-//   todayNumber.value = todaySignIn.value ? continuousDay.value - 1 : continuousDay.value
-// }
-// 获取签到列表
-// async function getSignIn () {
-//   try {
-//     const { data } = await getRewardSignInConfigList()
-//     SignItems.value = data
-//   } catch (error) {
-    
-//   }
-// }
-// 签到
-// async function handleSignIn () {
-//   uni.showLoading({
-//     title: '正在签到'
-//   })
-//   try {
-//     const { code } = await createRewardSignInRecord()
-//     if (code !== 0) {
-//       return
-//     }
-//     setTimeout(async () => {
-//       const { code: _code } = await getSummary()
-//       if (_code !== 0) {
-//         return
-//       }
-//       uni.showToast({
-//         title: '签到成功',
-//         icon: 'success',
-//         mask: true
-//       })
-//       // 更新积分
-//       getBalance()
-//     }, 1000)
-//   } catch (error) {
-    
-//   } finally {
-//     uni.hideLoading()
-//   }
-// }
-
-function handleLogin () {
-  if (!useUserStore.isLogin) {
-		showAuthModal()
-		return
-	}
-}
-
-function toInfo () {
-  uni.navigateTo({
-		url: '/pagesA/info/index'
-	})
-}
-
-function handleTo (page) {
-  if (!useUserStore.isLogin) {
-		showAuthModal()
-		return
-  }
-  if (showNecessaryInfoPopup()) {
-		uni.showToast({
-			title: '请先完善基本信息',
-			icon: 'none'
-		})
-		showAuthModal('necessaryInfo')
-		return
-	}
-  uni.navigateTo({
-    url: `/pagesA/${page}/index`
-  })
-}
-</script>
-
-<style scoped lang="scss">
-.shareQrCodePopupContent {
-	width: 75vw;
-	padding: 40rpx;
-	margin-bottom: 20rpx;
-	text-align: center;
-	background-color: #fff;
-}
-.box {
-  overflow: hidden;
-  height: 100vh;
-  padding: 20rpx 0 0 0;
-  box-sizing: border-box;
-  .scrollBox{
-    height: 100%;
-    
-    padding-bottom: 120rpx;
-    box-sizing: border-box;
-  }
-  .content {
-    padding-bottom: 24rpx;
-    box-sizing: border-box;
-  }
-  .wallet {
-    box-sizing: border-box;
-    height: 200rpx;
-    margin-bottom: 20rpx;
-    &-content {
-      display: flex;
-      height: 100%;
-      border-radius: 10rpx;
-      background: #FFF;
-      
-      &-member {
-        width: 50%;
-        display: flex;
-        align-items: center;
-        position: relative;
-        &:after {
-          content: '';
-          position: absolute;
-          width: 4rpx;
-          height: 30%;
-          right: 0;
-          top: 35%;
-          background: #00B760;
-        }
-        .iconBox {
-          width: 100rpx;
-          height: 100%;
-          display: flex;
-          align-items: center;
-          justify-content: center;
-          &-line {
-            border: 4rpx solid #ffbc00;
-            border-radius: 180rpx;
-            padding: 10rpx;
-          }
-        }
-        .name {
-          flex: 1;
-          .actvie {
-            color: #ffbc00;
-          }
-          
-        }
-      }
-      &-item {
-        width: 25%;
-        display: flex;
-        flex-direction: column;
-        align-items: center;
-        justify-content: center;
-        .title {
-          font-size: .85em;
-        }
-      }
-      &-integral {
-      }
-      &-cash {
-        
-      }
-    }
-  }
-  .signIn {
-    // padding: 0 20rpx;
-    box-sizing: border-box;
-    &-content {
-      border-radius: 10rpx;
-      background: #FFF;
-      &-items {
-        padding: 20rpx 20rpx;
-        display: flex;
-        height: 220rpx;
-        box-sizing: border-box;
-        .item {
-          height: 140rpx;
-          width: 100%;
-          align-items: center;
-          justify-content: center;
-          padding: 0 10rpx;
-          .box {
-            height: 100%;
-            width: 100%;
-            display: flex;
-            flex-direction: column;
-            background: #f2f4f7;
-            border-radius: 10rpx;
-            &.active {
-              color: #fff;
-              background: rgba(16,137,123, .66);
-            }
-            .text {
-              font-size: .75em;
-              text-align: center;
-            }
-          }
-          .day {
-            margin-top: 10rpx;
-            height: 60rpx;
-            text-align: center;
-            font-size: .5em;
-          }
-        }
-      }
-      .tips {
-        display: flex;
-        align-items: center;
-        justify-content: flex-end;
-        height: 80rpx;
-        font-size: .75em;
-        color: #999;
-        &-light {
-          color: #00B760;
-          padding: 0 10rpx;
-        }
-        button {
-          width: 180rpx;
-          height: 60rpx;
-          font-size: 24rpx;
-          margin: 0 10rpx;
-          border: unset;
-          background-color: #00B760;
-          color: #FFF;
-          &.disabled {
-            // background-color: #a7a7a7 !important;
-            opacity: .5;
-          }
-        }
-      }
-      
-    }
-  }
-  .goods {
-    padding: 0 15upx;
-		display: flex;
-		flex-wrap: wrap;
-		justify-content: space-between;
-    &-item {
-      background: #FFFFFF;
-      width: 48%;
-      margin: 10upx 0;
-      box-sizing: border-box;
-      &-img {
-        width: 100%;
-        height: 250upx;
-        display: block;
-        margin: auto;
-      }
-      &-price {
-        padding-top: 10upx;
-        color: #00B760;
-        font-size: 32upx;
-      }
-      &-name {
-        width: 100%;
-        white-space: nowrap;
-        font-size: 28upx;
-        line-height: 50upx;
-        padding-bottom: 10upx;
-        padding-top: 10upx;
-        overflow:hidden; 
-        text-overflow:ellipsis;
-        -webkit-box-orient:vertical;
-        -webkit-line-clamp:2; 
-      }
-    }
-  }
-}
-:deep(.uni-section .uni-section-header__decoration) {
-  background-color: #00B760 !important;
-}
-</style>

+ 48 - 0
pages/loading/index.vue

@@ -0,0 +1,48 @@
+<template>
+  <view class="box">
+    <image class="img" src="https://minio.menduner.com/dev/fe9890be9b1176f84f2aa282b0f6adce300b133f65eb3d7b45ae057aa5698324.png"></image>
+    <view class="color-primary font-size-20 font-weight-bold">我是大女主</view>
+    <view class="icons">
+      <uni-icons type="spinner-cycle" size="24" />
+    </view>
+  </view>
+</template>
+
+<script setup>
+import { onShow } from '@dcloudio/uni-app'
+// import { getAccessToken } from '@/utils/request'
+// import { showAuthModal } from '@/hooks/useModal'
+// import { userStore } from '@/store/user'
+// const useUserStore = userStore()
+
+// const tabBarControl = (show = false) => { // 显示/隐藏 TabBar
+//   const currentPage = getCurrentPages()
+//   if (!currentPage) return
+//   const currentTabBar = currentPage[0]?.getTabBar?.()
+//   currentTabBar?.setData({ show })
+// }
+
+onShow(async() => {
+  // tabBarControl(false) // 隐藏页面底部导航
+  
+	// if (!getAccessToken()) showAuthModal()
+  uni.reLaunch({ url: 'pages/drawLots/index' })
+})
+</script>
+<style lang="scss" scoped>
+.box {
+  text-align: center;
+  .img {
+    width: 105px;
+    height: 45px;
+    margin-top: 30vh;
+    margin-bottom: 16px;
+  }
+  .icons {
+    position: fixed;
+    bottom: 20vh;
+    width: 100%;
+    margin: 0 auto;
+  }
+}
+</style>

+ 0 - 200
pages/register/contact.vue

@@ -1,200 +0,0 @@
-<template>
-	<view class="f-straight wrapper">
-		<!-- <uni-notice-bar class="ss-m-b-30" scrollable text="填写联系人1后可获得500积分,可前往【门墩儿商城】兑换礼品【减压捏捏乐】,企业注册审核通过后积分将自动发放到您的账户中。" /> -->
-		<view v-for="(val, index) in contacts" :key="index" class="f-straight contact-item">
-			<view class="d-flex justify-space-between align-center ss-m-b-20">
-				<view class="color-primary">{{ index === 0 ? '管理员' : '联系人' + index }}</view>
-				<view v-if="index > 1">
-					<uni-icons type="closeempty" size="20" color="#fe574a" @click="deleteContact(index)"></uni-icons>
-				</view>
-			</view>
-			<uni-forms ref="formRef" :modelValue="val" :rules="formRules" validateTrigger="bind" label-width="105px" label-align="right" label-position="left">
-				<uni-forms-item name="contactName" label="联系人姓名" required>
-					<uni-easyinput v-model="val.contactName" placeholder="请输入"></uni-easyinput>
-				</uni-forms-item>
-				<uni-forms-item name="phone" label="联系电话" required>
-					<uni-easyinput v-model="val.phone" placeholder="请输入" :disabled="index === 0"></uni-easyinput>
-				</uni-forms-item>
-				<uni-forms-item name="email" label="企业邮箱" required>
-					<uni-easyinput v-model="val.email" placeholder="请输入企业邮箱(用于日后“登录邮箱”)"></uni-easyinput>
-				</uni-forms-item>
-				<uni-forms-item name="password" label="账户登录密码" required>
-					<uni-easyinput v-model="val.password" placeholder="请输入" type="password"></uni-easyinput>
-				</uni-forms-item>
-				<uni-forms-item name="passwordConfirm" label="密码二次确认" required>
-					<uni-easyinput v-model="val.passwordConfirm" placeholder="请输入" type="password"></uni-easyinput>
-				</uni-forms-item>
-			</uni-forms>
-		</view>
-		<view class="color-warning" style="text-align: center; margin-bottom: 50px;" @tap.stop="handleAddContact">
-			<uni-icons type="plusempty" size="20" color="#fb8c00"></uni-icons>
-			继续添加联系人
-		</view>
-
-		<button class="send-button" @tap="handleSubmit">提 交</button>
-	</view>
-</template>
-
-<script setup>
-import { ref, computed } from 'vue'
-import { userStore } from '@/store/user'
-import { onLoad } from '@dcloudio/uni-app'
-import { mobile, emailRequired, password } from '@/utils/validate'
-import { enterpriseRegisterApply } from '@/api/enterprise'
-
-const useUserStore = userStore()
-const adminUserPhone = computed(() => useUserStore?.phone)
-const register = ref(JSON.parse(uni.getStorageSync('registerInfo')))
-console.log(adminUserPhone.value, '注册手机号', register.value)
-
-const formRef = ref()
-const formRules = {
-	contactName: {
-		rules: [{required: true, errorMessage: '请输入姓名' }]
-	},
-  phone: mobile,
-	email: emailRequired,
-	password,
-	passwordConfirm: {
-		rules: [
-			{ required: true, errorMessage: '请再次输入密码' },
-			{ 
-				validateFunction: function(rule, value, data, callback) {
-					if (value !== data.password) callback('两次输入的密码不一致')
-					return true
-				}
-			}
-		]
-	}
-}
-
-const contacts = ref([
-  {
-    contactName: '',
-    phone: adminUserPhone.value || '',
-    email: '',
-    password: '',
-    passwordConfirm: ''
-  },
-  {
-    contactName: '',
-    phone: '',
-    email: '',
-    password: '',
-    passwordConfirm: ''
-  }
-])
-
-onLoad((options) => {
-	if (options?.isEdit) {
-		const applyInfo = ref(uni.getStorageSync('entRegisterData') ? JSON.parse(uni.getStorageSync('entRegisterData')) : {})
-		contacts.value = applyInfo.value.contacts.map(e =>  {
-			e.passwordConfirm = e.password
-			return e
-		})
-	}
-})
-
-const handleAddContact = () => {
-	contacts.value.push({
-		contactName: '',
-		phone: '',
-		email: '',
-		password: '',
-		passwordConfirm: ''
-	})
-}
-
-const deleteContact = (index) => {
-	contacts.value.splice(index, 1)
-}
-
-// 检查联系人信息是否重复
-const checkDuplicates = (dataList) => {
-  const emailRecord = {}
-  const phoneRecord = {}
-  for (const item of dataList) {
-    const email = item.email
-    const phone = item.phone
-    if (emailRecord[email]) {
-      return false
-    }
-    if (phoneRecord[phone]) {
-      return false
-    }
-    emailRecord[email] = true
-    phoneRecord[phone] = true
-  }
-  return true
-}
-
-const handleSubmit = async () => {
-  // 存储所有的验证Promise
-  const validationPromises = []
-  formRef.value.forEach((e) => {
-    validationPromises.push(e.validate().catch(err => {
-      return false
-    }))
-  })
-
-  // 等待所有验证Promise完成
-  const validationResults = await Promise.all(validationPromises)
-  const errorCount = validationResults.filter(result => result === false).length
-  if (errorCount > 0) return
-
-  if (!contacts.value.length || contacts.value.length < 2) {
-    uni.showToast({
-      title: '请至少添加两个联系人',
-      icon: 'none',
-      duration: 2000
-    })
-    return
-  }
-
-  const checkValue = checkDuplicates(contacts.value)
-  if (!checkValue) {
-    uni.showToast({
-      title: '手机号或邮箱不能重复',
-      icon: 'none',
-      duration: 2000
-    })
-    return
-  }
-
-	const params = {
-		...register.value,
-		contacts: contacts.value,
-		contactName: contacts.value[0].contactName,
-		phone: contacts.value[0].phone,
-		email: contacts.value[0].email
-	}
-	console.log(params, '企业注册参数')
-
-	uni.showLoading({ title: '提交中' })
-	try {
-		await enterpriseRegisterApply(params)
-		uni.hideLoading()
-		uni.showToast({
-			title: '提交成功',
-			icon: 'success',
-			duration: 2000
-		})
-		uni.removeStorageSync('entRegisterData') // 重新提交时清除前面的缓存,否则重新提交申请后再刷会显示旧数据
-		uni.reLaunch({
-			url: '/pages/register/review?applySubmit=true'
-		})
-	} catch {
-		uni.hideLoading()
-	}
-}
-</script>
-
-<style lang="scss" scoped>
-.wrapper{
-	padding: 15px;
-}
-.contact-item {
-	border-bottom: 1px solid #eee;
-	margin-bottom: 30px;
-}
-</style>

+ 0 - 220
pages/register/index.vue

@@ -1,220 +0,0 @@
-<template>
-  <view class="f-straight wrapper">
-    <uni-forms ref="formRef" :modelValue="formData" :rules="formRules" validateTrigger="bind" label-width="105px" label-align="right" label-position="left">
-      <uni-forms-item name="prepare" label="筹备中" required>
-        <uni-data-checkbox 
-          v-model="formData.prepare" 
-          selectedColor="#00B760" 
-          selectedTextColor="#00B760" 
-          :localdata="[{ text: '是', value: true }, { text: '否', value: false }]"
-          @change="handleChangePrepare"
-        />
-      </uni-forms-item>
-      <uni-forms-item name="businessLicenseUrl" label="营业执照" :required="required['businessLicenseUrl']">
-        <view style="display: flex;flex-wrap: wrap;">
-          <view class="upload-img" v-if="formData?.businessLicenseUrl">
-            <uni-icons size="35" type="clear" color="#fe574a" style="position: absolute; right: -15px; top: -15px; z-index: 9" @click="handleDeleteImg"></uni-icons>
-            <image :src="formData?.businessLicenseUrl" mode="contain" style="width: 200rpx;height: 200rpx;" @click="handlePreviewImage"></image>
-          </view>
-          <view v-else class="upload-file" @click="uploadPhotos">
-            <uni-icons type="plusempty" size="50" color="#f1f1f1"></uni-icons>
-          </view>
-          <view class="ss-m-t-10 color-999">上传营业执照支持jpg、jpeg、png格式,图片大小不得超过20M</view>
-        </view>
-      </uni-forms-item>
-      <uni-forms-item name="name" label="企业名称" required>
-        <uni-easyinput v-model="formData.name" placeholder="请输入"></uni-easyinput>
-        <view class="ss-m-t-10 color-999">注:需与营业执照一致,上传营业执照可自动识别</view>
-      </uni-forms-item>
-      <uni-forms-item name="anotherName" label="对外展示名称" required>
-        <uni-easyinput v-model="formData.anotherName" placeholder="请输入"></uni-easyinput>
-      </uni-forms-item>
-      <uni-forms-item name="code" label="社会信用代码" :required="required['code']">
-        <uni-easyinput v-model="formData.code" placeholder="请输入"></uni-easyinput>
-        <view class="ss-m-t-10 color-999">注:需与营业执照一致,上传营业执照可自动识别</view>
-      </uni-forms-item>
-      <uni-forms-item name="description" label="备注/说明">
-        <uni-easyinput v-model="formData.description" placeholder="请输入" type="textarea"></uni-easyinput>
-      </uni-forms-item>
-    </uni-forms>
-
-    <button class="send-button" @tap="handleNext">下一步</button>
-  </view>
-</template>
-
-<script setup>
-// 扫码登录注册
-import { ref, unref } from 'vue'
-import { uploadFile } from '@/api/file'
-import { getBusinessLicenseOCR } from '@/api/common'
-
-const formRef = ref()
-const formData = ref({
-  prepare: true,
-  businessLicenseUrl: '',
-  name: '',
-  anotherName: '',
-  code: '',
-  description: ''
-})
-
-const required = ref({
-  code: false,
-  businessLicenseUrl: false
-})
-
-const formRules = ref({
-	name:{
-		rules: [{required: true, errorMessage: '请输入企业名称' }]
-	},
-  anotherName:{
-		rules: [{required: true, errorMessage: '请输入企业对外展示名称' }]
-	},
-	prepare: {
-		rules: [{required: true, errorMessage: '请选择贵企业是否在筹备中' }]
-	}
-})
-
-// 图片预览
-const handlePreviewImage = () => {
-  uni.previewImage({
-    current: 0,
-    urls: [formData.value.businessLicenseUrl]
-  })
-}
-
-// 图片删除
-const handleDeleteImg = () => {
-  formData.value.businessLicenseUrl = ''
-  business.value = {}
-  formData.value.ocr = null
-  formData.value.code = ''
-  formData.value.name = ''
-}
-
-// 识别营业执照图片
-const business = ref({})
-const getOcr = async () => {
-  uni.showLoading({ title: '识别中...' })
-  try {
-    const { data } = await getBusinessLicenseOCR(formData.value.businessLicenseUrl)
-    if (data && Object.keys(data).length) {
-      formData.value.code = data.code
-      formData.value.name = data.name
-      business.value = data
-    } else {
-      formData.value.businessLicenseUrl = ''
-      uni.showToast({
-        title: '识别失败,请重新上传清晰合法图片',
-        icon: 'none',
-        duration: 2000
-      })
-    }
-  } catch (error) {
-    formData.value.businessLicenseUrl = ''
-    console.error(error, 'error')
-    uni.hideLoading()
-    uni.showToast({
-      title: '识别失败,请重新上传清晰合法图片',
-      icon: 'none',
-      duration: 2000
-    })
-  } finally {
-    uni.hideLoading()
-  }
-}
-
-// 选择营业执照
-const uploadPhotos = () => {
-  wx.chooseImage({
-    count: 1,
-    sizeType: ['original', 'compressed'],
-    sourceType: ['album', 'camera'],
-    success: function(res){
-      const size = res.tempFiles[0]?.size || 0
-      if (size >= 31457280) {
-        uni.showToast({
-          icon: 'none',
-          title: '上传图片大小不得超过 20MB !',
-          duration: 2000
-        })
-        return
-      }
-      const path = res.tempFilePaths[0]
-      uploadFile(path, 'img').then(res => {
-        formData.value.businessLicenseUrl = res.data
-        getOcr()
-      }).catch(error => {
-        uni.showToast({
-          icon: 'error',
-          title: '图片上传失败!',
-          duration: 2000
-        })
-      })
-    }
-  })
-}
-
-// 是否筹备中
-const handleChangePrepare = (e, clear = true) => {
-  const prepare = e.detail.value
-  for(let i in required.value) {
-    required.value[i] = !prepare
-  }
-  formRules.value.code = { rules: !prepare ? [{required: true, errorMessage: '请填写统一社会信用代码' }] : [] }
-  formRules.value.businessLicenseUrl = { rules: !prepare ? [{required: true, errorMessage: '请上传营业执照' }] : [] }
-  if (clear) formRef.value.clearValidate()
-}
-
-// 申请拒绝-重新提交数据回显
-const applyInfo = ref(uni.getStorageSync('entRegisterData') ? JSON.parse(uni.getStorageSync('entRegisterData')) : {})
-console.log(applyInfo.value, '申请拒绝-重新提交数据回显')
-if (applyInfo.value && Object.keys(applyInfo.value).length > 0 && applyInfo.value.status === '2') {
-  for (let i in formData.value) {
-    formData.value[i] = applyInfo.value[i]
-  }
-  business.value = applyInfo.value?.orc || {}
-  handleChangePrepare({ detail: { value: applyInfo.value.prepare }}, false)
-}
-
-// 登录
-const handleNext = async () => {
-  const validate = await unref(formRef).validate()
-  if (!validate) return
-
-  if (business.value && Object.keys(business.value).length) formData.value.ocr = business.value
-  
-  const isEdit = applyInfo.value && Object.keys(applyInfo.value).length > 0 && applyInfo.value.status === '2'
-  if (isEdit) formData.value.id = applyInfo.value.id
-  console.log(formData.value, 'index-next-formData')
-
-  uni.setStorageSync('registerInfo', JSON.stringify(formData.value))
-  uni.navigateTo({
-    url: isEdit ? '/pages/register/contact?isEdit=true' : '/pages/register/contact'
-  })
-}
-</script>
-
-<style scoped lang="scss">
-.wrapper{
-	padding: 15px;
-  padding-top: 30px;
-}
-.upload-img{
-  position: relative;
-  width: 200rpx;
-  height: 200rpx;
-  border: 1px solid #f1f1f1;
-  margin: 10rpx;
-}
-.upload-file{
-  width: 200rpx;
-  height: 200rpx;
-  border: 1px solid #f1f1f1;
-  margin: 10rpx;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  border-radius: 10rpx;
-}
-</style>

+ 0 - 155
pages/register/phoneValidate.vue

@@ -1,155 +0,0 @@
-<template>
-  <view class="ss-p-30">
-      <view class="head-title ss-m-b-30">请输入您申请企业账号时填入的手机号进行效验</view>
-
-      <view class="ss-m-t-50">
-        <uni-forms
-					ref="smsLoginRef"
-					v-model="state.sms"
-					:rules="state.smsRules"
-					validateTrigger="bind"
-					labelWidth="140"
-					labelAlign="center"
-				>
-					<uni-forms-item name="phone" label="手机号">
-						<uni-easyinput placeholder="请输入手机号" v-model="state.sms.phone" :inputBorder="false" type="number">
-						</uni-easyinput>
-					</uni-forms-item>
-
-					<uni-forms-item name="code" label="验证码">
-						<uni-easyinput
-							placeholder="请输入验证码"
-							v-model="state.sms.code"
-							:inputBorder="false"
-							type="number"
-							maxlength="6"
-						>
-							<template v-slot:right>
-								<button
-									class="login-code"
-									:disabled="state.isMobileEnd"
-									:class="{ 'code-btn-end': state.isMobileEnd }"
-									@tap="handleCode"
-								>
-									{{ getSmsTimer('smsRegister') }}
-								</button>
-							</template>
-						</uni-easyinput>
-					</uni-forms-item>
-				</uni-forms>
-
-        <button class="send-button" @tap="handleLogin"> 验 证  </button>
-      </view>
-  </view>
-</template>
-
-<script setup>
-import { ref, unref } from 'vue'
-import { mobile, code } from '@/utils/validate'
-import { getSmsCode, getSmsTimer } from '@/utils/code'
-import { userStore } from '@/store/user'
-import { onLoad } from '@dcloudio/uni-app'
-import { closeAuthModal } from '@/hooks/useModal'
-
-const useUserStore = userStore()
-const smsLoginRef = ref()
-const state = ref({
-  isMobileEnd: false, // 手机号输入完毕
-  codeText: '获取验证码',
-  sms: {
-    phone: '',
-    code: ''
-  },
-  smsRules: {
-    code,
-    phone: mobile
-  }
-})
-
-onLoad((options) => {
-	if (options.phone) state.value.sms.phone = options.phone
-})
-
-// 获取验证码
-const handleCode = () => {
-  if (!state.value.sms.phone) {
-    uni.showToast({
-      title: '请输入手机号',
-      icon: 'none',
-      duration: 2000
-    })
-    return
-  }
-  getSmsCode('smsLogin', state.value.sms.phone)
-}
-
-// 验证
-const handleLogin = async () => {
-  const validate = await unref(smsLoginRef).validate()
-  if (!validate) return
-  const query = state.value.sms
-  Object.assign(query, {
-    sms: query.phone
-  })
-  console.log(query, '手机号效验参数')
-	try {
-		await useUserStore.handleSmsLogin(query, 0, false)
-		uni.showToast({
-			title: '手机号效验成功',
-			icon: 'none',
-			duration: 2000
-		})
-		closeAuthModal()
-		uni.navigateTo({
-			url: '/pages/register/index'
-		})
-	} catch (err) {
-		closeAuthModal()
-		console.log(err, '手机号效验')
-	}
-}
-</script>
-
-<style scoped lang="scss">
-.login-code {
-  width: 73px;
-  min-width: 73px;
-  color: #00B760;
-  text-align: center; 
-  font-size: 12px; 
-  cursor: pointer;
-  padding: 0;
-}
-.head-title {
-  font-size: 40rpx;
-  text-align: center;
-  color: #00B760;
-  margin-top: 30rpx;
-}
-.quickLogon {
-  display: flex;
-  justify-content: space-between;
-  padding: 0 20rpx;
-  align-items: center;
-}
-.wxLogon {
-  font-size: .85em;
-  color: #00B760;
-  border: none;
-  margin: 0;
-  padding: 0;
-}
-.register {
-  widows: 100%;
-  font-size: .85em;
-  color: red;
-  // text-align: right;
-  &.login {
-    color: #00B760;
-  }
-}
-.pb-20 {
-  padding-bottom: 40rpx;
-}
-
-</style>

+ 0 - 158
pages/register/review.vue

@@ -1,158 +0,0 @@
-<template>
-	<view v-if="show" style="padding: 15px;">
-		<!-- 提交企业注册以后跳转显示页面 -->
-		<view v-if="!applyInfo?.status">
-			<view class="d-flex flex-column align-center">
-				<image src="/static/svg/submit.svg" style="height: 200px; width: "></image>
-			</view>
-			<view class="text-center"><span class="color-primary font-size-20 font-weight-bold">您的企业注册申请已提交</span></view>
-      <view class="mt-5">审核时间预计在1~3个工作日内,申请结果会以短信方式通知到您的手机上,请注意查收。</view>
-      <view style="width: 100%;">
-        <view class="mt-5 mb-1">如有疑问请长按二维码添加下方企业微信联系我们:</view>
-        <view style="width: 150px; height: 150px; margin: auto;">
-					<image show-menu-by-longpress="true" src="https://minio.menduner.com/dev/9e7a28d32e2eb72794e2051c88573eb4cb1e44c8bfff7e2f9f7ffe458f3a55df.png" style="width: 150px; height: 150px;"></image>
-        </view>
-        <view class="text-center ml-5">潘青海先生(Peter Pan)</view>
-      </view>
-			<button class="recomm-button" @tap="refresh">刷新结果</button>
-		</view>
-		<!-- 等待审核 -->
-		<view v-else-if="applyInfo?.status === '0'">
-			<view class="d-flex flex-column align-center">
-				<image src="/static/svg/submit.svg" style="height: 200px; width: "></image>
-			</view>
-			<view>
-        您的企业账号申请<span class="color-primary font-size-20 font-weight-bold"> 正在审核中,</span>审核时间在1~3个工作日内,申请结果会以短信方式通知到您的手机上,请注意查收。
-      </view>
-      <view class="ss-m-t-30">
-        <span>提交时间:{{ applyInfo.createTime }}</span>
-      </view>
-      <view style="width: 100%;">
-        <view class="mt-5 mb-1">如有疑问请长按二维码添加下方企业微信联系我们:</view>
-        <view style="width: 150px; height: 150px; margin: auto;">
-					<image show-menu-by-longpress="true" src="https://minio.menduner.com/dev/9e7a28d32e2eb72794e2051c88573eb4cb1e44c8bfff7e2f9f7ffe458f3a55df.png" style="width: 150px; height: 150px;"></image>
-        </view>
-        <view class="text-center ml-5">潘青海先生(Peter Pan)</view>
-      </view>
-			<button class="recomm-button" @tap="refresh">刷新结果</button>
-		</view>
-
-		<!-- 审核不通过 -->
-		<view v-else-if="applyInfo?.status === '2'" class="ss-m-b-100">
-			<view class="ss-m-b-20 color-error">
-        您的企业账号注册申请<span class="color-error font-size-20 font-weight-bold"> 审核不通过</span>
-      </view>
-			<view class="ss-m-b-20 color-error">具体原因如下:{{ applyInfo.reason }}</view>
-      <view v-if="applyInfo.remark">备注:{{ applyInfo.remark }}</view>
-      <view class="mt-5">
-        <span>审核时间:{{ applyInfo.updateTime }}</span>
-      </view>
-      <view>
-        <span>提交时间:{{ applyInfo.createTime }}</span>
-      </view>
-      <view style="width: 100%;">
-        <view class="mt-5 mb-1">如有疑问请长按二维码添加下方企业微信联系我们:</view>
-        <view style="width: 150px; height: 150px; margin: auto;">
-          <image show-menu-by-longpress="true" src="https://minio.menduner.com/dev/9e7a28d32e2eb72794e2051c88573eb4cb1e44c8bfff7e2f9f7ffe458f3a55df.png" style="width: 150px; height: 150px;"></image>
-        </view>
-        <view class="text-center ml-5">潘青海先生(Peter Pan)</view>
-      </view>
-			<button class="recomm-button" @tap="handleConfirm">重新提交</button>
-			<button class="recomm-button" @tap="refresh">刷新结果</button>
-		</view>
-		
-		<!-- 审核通过  -->
-		<view v-else-if="applyInfo?.status === '1'" class="ss-m-b-100">
-			<view class="d-flex flex-column align-center">
-				<image src="/static/svg/submit.svg" style="height: 200px; width: "></image>
-			</view>
-			<view class="text-center"><span class="color-primary font-size-20 font-weight-bold">您的企业注册申请已通过</span></view>
-			<button class="recomm-button" @tap="toLogin">前往门墩儿招聘</button>
-		</view>
-	</view>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import { getUserRegisterEnterpriseApply } from '@/api/enterprise.js'
-import { timesTampChange } from '@/utils/date'
-import { onLoad, onShow } from '@dcloudio/uni-app'
-import { userStore } from '@/store/user'
-
-const user = userStore()
-const applyInfo = ref({})
-const show = ref(false)
-
-// 查看用户是否有在申请中的数据
-const getApplyInfo = async () => {
-	// 已经有数据说明已经申请过了
-	let result = {}
-	if (hasData && uni.getStorageSync('entRegisterData')) {
-		result = JSON.parse(uni.getStorageSync('entRegisterData'))
-	} else {
-		const { data } = await getUserRegisterEnterpriseApply()
-		result = data || {}
-		uni.setStorageSync('entRegisterData', JSON.stringify(result))
-	}
-
-  applyInfo.value = {
-		phone: result.phone,
-    createTime: timesTampChange(result.createTime), // 创建时间
-    updateTime: timesTampChange(result.updateTime), // 更新时间
-    status: result.status, // 审核状态(0审核中 1审核通过 2审核不通过)) // 审核状态
-    reason: result.reason, // 审核原因
-    remark: result.remark // 备注
-  }
-  console.log(result, 'review----查看是否有申请中的数据', applyInfo.value)
-}
-
-let hasData = false
-onLoad((options) => {
-	hasData = options?.hasData ? true : false
-
-	// 刚提交审核,只显示提交页面,不查询审核状态,刷新后再显示申请状态
-	if (options?.applySubmit) return
-	getApplyInfo()
-})
-
-onShow(() => {
-	show.value = true
-})
-
-const refresh = async () => {
-	hasData = false
-	await getApplyInfo()
-	uni.showToast({ title: '刷新成功', icon: 'success', duration: 1500 })
-}
-
-// 回到首页时需将当前个人登录状态及缓存中的数据清除
-const handleToHome = async () => {
-	await user.handleUserLogout()
-	uni.removeStorageSync('isPersonalToken') // 注册企业时个人登录
-	uni.reLaunch({
-		url: '/pages/index/my'
-	})
-}
-
-// 进入平台时需将当前个人登录状态及缓存中的数据清除
-const toLogin = async () => {
-	await user.handleUserLogout()
-	uni.removeStorageSync('token');
-	uni.removeStorageSync('refresh-token');	
-	uni.removeStorageSync('isPersonalToken') // 注册企业时个人登录
-  uni.reLaunch({ url: '/pages/index/search' }) // 进入门墩儿
-}
-
-const handleConfirm = () => {
-	if (uni.getStorageSync('token') && uni.getStorageSync('isPersonalToken')) {
-		uni.navigateTo({ url: '/pages/register/index' })
-		return
-	}
-	uni.reLaunch({
-		url: `/pages/register/phoneValidate?phone=${applyInfo.value?.phone}`
-	})
-}
-</script>
-
-<style scoped lang="scss">
-</style>

+ 0 - 743
pagesA/chart/index.vue

@@ -1,743 +0,0 @@
-<template>
-  <view>
-    <Navbar :textLeft="false" title="我的聊天" />
-    <view class="box defaultBgc MiSans-Normal" :style="{'padding-top': navbarHeight + 'px', height: 'calc(100vh - ' + navbarHeight + 'px)'}">
-      <view class="commonBackground"></view>
-      <view class="box-top">
-        <image class="box-top-image" :src="getUserAvatar(info.avatar, info.sex, info.channelID === 'system' ? true : false)" ></image>
-        <view class="box-top-right MiSans-Normal">
-          <view class="box-top-right-title">{{ info.name }}</view>
-        </view>
-      </view>
-
-
-        <!-- newsId 需要和聊天列表里面的id对应 永远取最后列表中的最后一个就可以做到发送消息即时滚动到底部 -->
-        <scroll-view ref="chatRef" :scroll-with-animation="scrollAnimation" :scroll-into-view="newsId" class="box-main" scroll-y="true">
-          <view class="box-main-more" v-if="hasMore">
-            <text @click="handleMore">查看更多</text>
-          </view>
-          <view v-for="(val, index) in items" :key="val.id" :id="'s'+val.id+index">
-            <view class="box-main-time">{{ timesTampChange(+(val.timestamp.padEnd(13, '0'))) }}</view>
-            <template v-if="val.payload?.type === 102">
-              <view class="jobCard">
-                <view class="jobCard-title"> {{ formatName(val.payload?.content?.positionInfo?.name) }}</view>
-                <view
-                  v-if="!val.payload?.content?.positionInfo?.payFrom && !val.payload?.content?.positionInfo?.payTo"
-                  class="jobCard-subtitle">
-                  薪酬待遇: 面议
-                </view>
-                <view
-                  v-else
-                  class="jobCard-subtitle"
-                >
-                  薪酬待遇: 
-                  {{ val.payload?.content?.positionInfo?.payFrom ? val.payload?.content?.positionInfo?.payFrom + ' - ' : '' }}
-                  {{ val.payload?.content?.positionInfo?.payTo }}
-                </view>
-                <view class="jobCard-tag">
-                  <view
-                    v-for="(v, i) in (val.payload?.content?.positionInfo?.enterprise?.welfareList || [])"
-                    :key="val.message_id + v + i"
-                    style="margin: 10rpx"
-                  >
-                    <uni-tag
-                      :text="v"
-                      type="success"
-                    />
-                  </view>
-                </view>
-                <view class="jobCard-divider"></view>
-                <view class="jobCard-subtitle text-right">
-                  <v-avatar size="24">
-                    <v-img :src="val.payload?.content?.positionInfo?.contact?.avatar"></v-img>
-                  </v-avatar>
-                  {{ val.payload?.content?.positionInfo?.contact?.name }}
-                  {{ val.payload?.content?.positionInfo?.contact?.postNameCn }}
-                  <!-- {{ formatName(val.payload?.content?.positionInfo?.enterprise?.anotherName || val.payload?.content?.positionInfo?.enterprise?.name) }} -->
-                </view>
-                <div class="jobCard-subtitle text-right">
-                  地址:{{ val.payload?.content?.positionInfo?.address }}
-                </div>
-              </view>
-            </template>
-            <!-- 面试邀请 -->
-            <template v-if="val.payload?.type === 101">
-              <view class="jobCard">
-                <view class="font-size-15 ss-m-b-20">面试邀请</view>
-                <view class="jobCard-title"> {{ formatName(val.payload?.content?.positionInfo?.data?.name) }}</view>
-                <view
-                  v-if="!val.payload?.content?.positionInfo?.data?.payFrom && !val.payload?.content?.positionInfo?.data?.payTo"
-                  class="jobCard-subtitle">
-                  薪酬待遇: 面议
-                </view>
-                <view v-else class="jobCard-subtitle">
-                  薪酬待遇: 
-                  {{ val.payload?.content?.positionInfo?.data?.payFrom ? val.payload?.content?.positionInfo?.data?.payFrom + ' - ' : '' }}
-                  {{ val.payload?.content?.positionInfo?.data?.payTo }}
-                </view>
-                <view class="font-size-15">面试时间: {{ timesTampChange(val.payload?.content?.time) }}</view>
-                <view class="font-size-15">面试地点: {{ val.payload?.content?.address }}</view>
-                <view class="font-size-15">联系电话: {{ val.payload?.content?.invitePhone }}</view>
-              </view>
-            </template>
-            <view :class="['message-view_item', val.from_uid === IM.uid ? 'is-self' : 'is-other']">
-              <view class="image">
-                <image
-                  :data-target="getUserAvatar(info.avatar, info.sex, info.channelID === 'system' ? true : false)"
-                  class="header"
-                  :src="(
-                    val.from_uid === IM.uid ?
-                    getUserAvatar(useUserStore.userInfo?.avatar, useUserStore.userInfo?.sex) :
-                    getUserAvatar(info.avatar, info.sex, info.channelID === 'system' ? true : false)
-                  )"
-                ></image>
-              </view>
-              <!-- 显示沟通职位 -->
-              <template v-if="val.payload?.type === 102">              
-                <view
-                  class="message-text" 
-                  :class="val.from_uid === IM.uid ? 'active' : ''" 
-                  :style="{'border-radius': val.from_uid === IM.uid ? '20rpx 20rpx 9rpx 20rpx' : '20rpx 20rpx 20rpx 9rpx'}"
-                >
-                  {{ val.payload?.content.text }}
-                </view>
-              </template>
-              <!-- 发起面试邀请 -->
-              <view class="message-text none" v-else-if="val.payload?.type === 101">
-                <uni-tag text="发起了面试邀请" custom-style="background-color: #00B760; border-color: #00B760; color: #fff;" />
-              </view>
-              <view class="message-text none" v-else-if="val.payload?.type === 103">
-                <uni-tag text="拒绝了面试邀请" type="error" />
-              </view>
-              <view class="message-text none" v-else-if="val.payload?.type === 104">
-                <uni-tag text="接受了面试邀请" custom-style="background-color: #00B760; border-color: #00B760; color: #fff;" />
-              </view>
-              <view v-else-if="val.payload.type === 105" class="text-end">
-                <uni-tag
-                  v-if="val.from_uid === IM.uid"
-                  :text="val.payload.content?.type === 1 ? '附件简历已发送' : '简历请求已发送'"
-                  custom-style="background-color: #00B760; border-color: #00B760; color: #fff;"
-                />
-                <view
-                  v-if="val.payload.content?.type !== 2 || val.from_uid !== IM.uid"
-                  class="message-text card"
-                >
-                  <view class="text-left">
-                    <text v-if="val.payload.content?.type === 1">{{
-                      val.payload.content?.query?.title || '附件简历' }}
-                    </text>
-                    <text v-if="val.payload.content?.type === 2">
-                      我想要一份您的简历,您是否同意
-                    </text>
-                  </view>
-                  <view class="btn-actions">
-                    <text class="btn" v-if="val.payload.content?.type === 1" @tap="handlePreview(val.payload)">点击预览附件简历</text>
-                  </view>
-                </view>
-              </view>
-              <view v-else-if="val.payload.type === -1" class="message-text" :class="{ active: val.from_uid === IM.uid}" style="border-radius: 20rpx 20rpx 20rpx 9rpx;">
-                {{ val.payload?.content?.text }}
-              </view>
-              <view 
-                v-else 
-                class="message-text" 
-                :class="{ active: val.from_uid === IM.uid}" 
-                :style="{'border-radius': val.from_uid === IM.uid ? '20rpx 20rpx 9rpx 20rpx' : '20rpx 20rpx 20rpx 9rpx'}">
-                {{ val.payload?.content }}
-              </view>
-            </view>
-          </view>
-        </scroll-view>
-        
-      <view class="box-bottom" v-if="channelItem?.channelID !== 'system'">
-        <view class="box-bottom-tool" style="display: flex; justify-content: start;">
-          <text class="toolBtn" @tap="handleFindResume">求简历</text>
-          <text class="toolBtn ss-m-l-30" @tap="handleInviteInterview">面试邀约</text>
-        </view>
-        
-        <view class="d-flex align-end textBox" v-if="channelItem?.channelID !== 'system'">
-          <textarea
-            v-model="inputValue"
-            :cursor-spacing="25"
-            :show-confirm-bar="false"
-            :disable-default-padding="true"
-            confirm-type="send"
-            auto-height
-            @confirm="handleSend"
-          />
-          <text class="submitBtn" @tap="handleSend">发 送</text>
-        </view>
-      </view>
-
-      <!-- 求简历 -->
-      <uni-popup ref="requestPopup" background-color="#fff" type="bottom">
-        <view style="background-color: #fff; height: 50vh; padding: 30px 20px;">
-          <uni-forms ref="requestFormRef" :modelValue="formData" :rules="formRules" validateTrigger="bind" label-width="80px" label-align="right" label-position="left">
-            <uni-forms-item name="jobId" label="招聘职位" required>
-              <view style="max-width: calc(100vw - 120px);">
-                <uni-data-select v-model="formData.jobId" :localdata="jobList"	@change="handleChangeJob"	placeholder="请选择要求简历的职位"></uni-data-select>
-              </view>
-            </uni-forms-item>
-          </uni-forms>
-          <view style="margin-top: 50px;"></view>
-          <button class="send-button" @tap="handleRequestSubmit">提 交</button>
-        </view>
-      </uni-popup>
-    </view>
-  </view>
-</template>
-
-<script setup>
-import { ref, watch, onMounted, computed, unref } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import { useIMStore } from '@/store/im'
-import { userStore } from '@/store/user'
-import { initConnect, send, initChart, getMoreMessages, toChannel } from '@/hooks/useIM'
-import { timesTampChange } from '@/utils/date'
-import { getUserAvatar } from '@/utils/avatar'
-import { formatName } from '@/utils/getText'
-import { preview } from '@/utils/preview'
-import { getAccessToken } from '@/utils/request'
-import { showAuthModal } from '@/hooks/useModal'
-import { getJobAdvertisedList } from '@/api/new/position'
-import Navbar from '@/components/Navbar'
-
-const navbarHeight = ref(uni.getStorageSync('navbarHeight'))
-const useUserStore = userStore()
-const userInfo = computed(() => useUserStore?.userInfo)
-
-const IM = useIMStore()
-const info = ref({})
-const chatRef = ref()
-const items = ref([])
-const channelItem = ref(null)
-const hasMore = ref(false)
-
-const pageSize = ref(1)
-
-const inputValue = ref('')
-
-const newsId = ref('') // newsId 需要和聊天列表里面的id对应 永远取最后列表中的最后一个就可以做到发送消息即时滚动到底部
-const scrollAnimation = ref(false)
-
-const isEmployment = ref('-1')
-
-onMounted(() => {
-  setTimeout(() => {
-    scrollAnimation.value = true
-  }, 1500)
-})
-
-const {
-  conversationList,
-  updateUnreadCount,
-  resetUnread
-} = initConnect(async (successful) => {
-  if (!successful) {
-    uni.showToast({
-      title: '发送失败',
-      icon: 'none',
-      mask: true,
-    })
-    return
-  }
-  inputValue.value = ''
-  // // 发送成功
-  const { list } = await getMoreMessages(1, channelItem.value)
-  items.value = list.value
-})
-
-watch(
-  () => conversationList.value,
-  async (val) => {
-    if (!channelItem.value) {
-      return
-    }
-    const { list } = await getMoreMessages(1, channelItem.value)
-    
-    items.value = list.value
-    setScrollBottom()
-    // 清除未读消息
-    resetUnread(channelItem.value, userInfo.value?.enterpriseId)
-  },
-  {
-    deep: true,
-    immediate: true
-  }
-)
-
-async function init(userId, enterpriseId) {
-  const { channel, list, more } = await initChart(userId, enterpriseId)
-  hasMore.value = more
-  channelItem.value = channel.value
-  items.value = list.value
-  setScrollBottom()
-}
-
-
-const setScrollBottom = () => {
-  if (items.value?.length) {
-    const lastOne = items.value[items.value.length-1]
-    const index = items.value.length-1
-    newsId.value = 's' + lastOne.id + index // newsId 需要和聊天列表里面的id对应 永远取最后列表中的最后一个就可以做到发送消息即时滚动到底部
-  }
-}
-
-function handleSend () {
-  if (!inputValue.value) {
-    uni.showToast({ title: '不能发送空白信息', icon: 'none' })
-    return
-  }
-  send(inputValue.value, channelItem.value)
-}
-
-// 职位列表
-const jobNum = ref(0)
-const jobList = ref([])
-const getJobList = async () => {
-  const { data } = await getJobAdvertisedList({ pageNo: 1, pageSize: 10, hasExpiredData: false, status: 0 })
-  jobNum.value = data?.total || 0
-  jobList.value = data?.list ? data?.list.map(e => {
-    return { text: formatName(e.name), value: e.id, ...e }
-  }) : []
-}
-
-// 求简历
-const requestPopup = ref()
-const requestFormRef = ref()
-const formData = ref({
-  jobId: null
-})
-const formRules = {
-	jobId: {
-		rules: [{ required: true, errorMessage: '请选择要求简历的职位' }]
-	}
-}
-const handleFindResume = async () => {
-  if (!getAccessToken()) {
-    showAuthModal()
-    return
-  }
-  // 企业必须有招聘中的职位才能发起面试邀请
-  if (jobNum.value === 0) {
-		uni.showToast({
-			title: '请先发布招聘职位',
-			icon: 'none',
-			duration: 2000
-		})
-		return
-	}
-  requestPopup.value.open()
-}
-
-const handleChangeJob = (e) => {
-  const job = jobList.value.find(item => item.value === e)
-	if (!job) return
-  formData.value.positionInfo = job
-}
-
-const handleRequestSubmit = async () => {
-  const valid = await unref(requestFormRef).validate()
-	if (!valid) return
-
-  const text = {
-    remark: '求简历',
-    query: {
-      src: '',
-      title: '',
-      id: '',
-      positionInfo: formData.value.positionInfo
-    },
-    type: 2
-  }
-  send (JSON.stringify(text), channelItem.value, 105)
-  formData.value = { jobId: null }
-  requestPopup.value.close()
-}
-
-// 邀约面试
-const handleInviteInterview = () => {
-  if (!getAccessToken()) {
-    showAuthModal()
-    return
-  }
-  // 企业必须有招聘中的职位才能发起面试邀请
-  if (jobNum.value === 0) {
-		uni.showToast({
-			title: '请先发布招聘职位',
-			icon: 'none',
-			duration: 2000
-		})
-		return
-	}
-
-  const chartData = {
-    ...channelItem.value,
-    id: info.value.id
-  }
-	uni.navigateTo({
-	  url: `/pagesB/InviteInterview/index?chartData=${encodeURIComponent(JSON.stringify(chartData))}`
-	})
-}
-
-// 预览简历
-function handlePreview (payload) {
-  if (!payload?.content?.query?.src) {
-    uni.showToast({ title: '简历地址不存在', icon: 'none' })
-    return
-  }
-  preview(payload.content.query.src)
-}
-
-// 查看更多
-async function handleMore () {
-  try {
-    uni.showLoading({
-      title: '加载中...'
-    })
-    pageSize.value++
-    const { list, more } = await getMoreMessages(pageSize.value, channelItem.value)
-    items.value.unshift(...list.value)
-    hasMore.value = more
-  } finally {
-    uni.hideLoading()
-  }
-}
-onLoad(async (options) => {
-  info.value = Object.keys(options).reduce((r, k) => {
-    r[k] = decodeURIComponent(options[k])
-    return r
-  }, {})
-  isEmployment.value = info.value.isEmployment
-  channelItem.value = toChannel(info.value.channelID, info.value.channelType)
-
-  if (channelItem.value.channelID === 'system') {
-    const { list, more } = await getMoreMessages(1, channelItem.value)
-    hasMore.value = more
-    items.value = list.value
-    setScrollBottom()
-    // 清除未读消息
-    resetUnread(channelItem.value, userInfo.value?.enterpriseId)
-    // 更新未读消息
-    updateUnreadCount()
-    return
-  }
-  await init(info.value.id, info.value.enterpriseId)
-
-  await getJobList() // 获取招聘中的职位
-
-  // 清除未读消息
-  resetUnread(channelItem.value, userInfo.value?.enterpriseId)
-  // 更新未读消息
-  updateUnreadCount()
-})
-</script>
-
-<style lang="scss" scoped>
-.text-left {
-  text-align: left !important;
-}
-.text-right {
-  text-align: right !important;
-}
-:deep {
-	.uni-select__selector-item {
-		display: block !important;
-		text-align: left !important;
-		max-width: 100% !important;
-		white-space: nowrap !important;
-		text-overflow: ellipsis !important;
-		overflow: hidden !important;
-	}
-}
-.box {
-  width: 100%;
-  display: flex;
-  flex-direction: column;
-  &-top {
-    z-index: 1;
-    padding: 30rpx 30rpx 0 30rpx;
-    display: flex;
-    justify-content: center;
-    &-image {
-      width: 80rpx;
-      height: 80rpx;
-      border-radius: 50%;
-      margin-right: 30rpx;
-    }
-    &-right {
-      flex: 1;
-      display: flex;
-      align-items: center;
-      &-title {
-        box-sizing: border-box;
-        width: 100%;
-        overflow: hidden;
-        white-space: nowrap;
-        text-overflow: ellipsis;
-        margin-bottom: 10rpx;
-      }
-      &-subText {
-        font-size: .85em;
-        color: #999;
-        .gun {
-          padding: 0 10rpx;
-        }
-      }
-    }
-    &-content {
-      padding: 20rpx 50rpx;
-      padding-bottom: 20rpx;
-      border-bottom: 2rpx solid #eee;
-      .color-666 {
-        color: #666;
-      }
-      .font-weight-bold {
-        font-weight: bold;
-      }
-      .color-primary {
-        color: #00B760;
-      }
-      .ml-3 {
-        margin-left: 40rpx;
-      }
-      .mt-1 {
-        margin-top: 12rpx;
-      }
-      .font-size-14 {
-        font-size: 24rpx;
-      }
-      .py-1 {
-        padding: 4rpx 0;
-      }
-      .tipsText {
-        font-size: .75em;
-        color: #999;
-      }
-      &-t {
-        display: flex;
-        justify-content: space-between;
-      }
-      .btnBox {
-        display: flex;
-        padding: 20rpx 60rpx;
-        justify-content: space-around;
-      }
-    }
-  }
-
-  &-main {
-    flex: 1;
-    height: 0;
-    padding: 40rpx;
-    // overflow-y: auto;
-    box-sizing: border-box;
-    &-more {
-      display: flex;
-      justify-content: center;
-      align-items: center;
-      color: #24bc3e;
-      font-size: .9em;
-      padding: 20rpx 0;
-    }
-    &-time {
-      user-select: none;
-      position: relative;
-      top: 16rpx;
-      margin: 40rpx 0;
-      text-align: center;
-      max-height: 40rpx;
-      text-align: center;
-      font-weight: 400;
-      font-size: .85em;
-      color: #999;
-    }
-    .jobCard {
-      padding: 30rpx;
-      background: #fbfbfb;
-      margin: 20rpx 5px;
-      max-width: unset;
-      border-radius: 20rpx;
-      box-shadow: 1px 2px 12px rgba(0, 0, 0, 0.1);
-      &-title {
-        font-weight: 600;
-        font-size: 36rpx;
-        margin-bottom: 30rpx;
-      }
-      &-subtitle {
-        padding: 10rpx 0;
-      }
-      &-tag {
-        display: flex;
-        flex-wrap: wrap;
-      }
-    }
-    .message-view_item {
-      display: flex;
-      flex-direction: row;
-      align-items: flex-end;
-      margin: 16rpx 0;
-      position: relative;
-      .image {
-        width: 60rpx;
-        height: 60rpx;
-        border-radius: 180rpx;
-        overflow: hidden;
-        .header {
-          width: 60rpx;
-          height: 60rpx;
-        }
-      }
-      .text-end {
-        text-align: right !important;
-        width: 400rpx;
-        margin-right: 20rpx;
-      }
-      .message-text {
-        overflow-wrap: break-word;
-        background-color: #00B760;
-        color: #fff;
-        border-radius: 20rpx 20rpx 20rpx 9rpx;
-        max-width: 75%;
-        padding: 20rpx;
-        font-family: MiSans-Normal;
-        &.active {
-          color: #fff;
-          background: #00B760;
-        }
-        &.card {
-          // background: #E2F2F0;
-          background: #fff;
-          color: #00B760 ;
-          margin-top: 20rpx;
-          max-width: unset;
-          margin-right: 0;
-          box-shadow: 1px 2px 12px rgba(0, 0, 0, 0.1);
-          .btn-actions {
-            margin: 40rpx auto 20rpx auto ;
-            text-align: center;
-            .btn {
-              padding: 10rpx 30rpx;
-              background: #C8E7D8;
-              color: #43AC57;
-              font-size: .75em;
-              border-radius: 10rpx;
-            }
-          }
-        }
-        &.none {
-          padding: 10rpx 0;
-          background-color: unset;
-        }
-        &.active {
-          background: #00B760;
-          color: #fff;
-        }
-      }
-    }
-    .is-self {
-      flex-direction: row-reverse;
-      display: flex;
-      .message-text {
-        margin-right: 20rpx;
-      }
-    }
-    .is-other {
-      .message-text {
-        margin-left: 20rpx;
-      }
-    }
-  }
-  &-bottom {
-    max-height: 300rpx;
-    border-top: 2rpx solid #EEE;
-    background: #fff;
-    padding: 20rpx 40rpx 40rpx;
-
-    box-sizing: border-box;
-    &-tool {
-      margin-bottom: 30rpx;
-      .toolBtn {
-        padding: 12rpx 20rpx;
-        font-size: 24rpx;
-        background: #00B760;
-        color: #FFF;
-        border-radius: 10rpx;
-      }
-    }
-    .textBox {
-      align-items: flex-end;
-    }
-    textarea {
-      border-radius: 10rpx;
-      width: 100%;
-      min-height: 80rpx;
-      max-height: 180rpx;
-      padding: 20rpx;
-      box-sizing: border-box;
-      background: #f5f5f5;
-    }
-    .submitBtn {
-      width: 140rpx;
-      line-height: 80rpx;
-      height: 80rpx;
-      font-size: 28rpx;
-      background: #00B760;
-      color: #FFF;
-      margin-left: 20rpx;
-      text-align: center;
-      border-radius: 10rpx;
-    }
-  }
-  .popup-title {
-    padding: 30rpx 20rpx;
-    display: flex;
-    justify-content: space-between;
-    border-bottom: 2rpx solid #DDD;
-  }
-  .popup-content {
-    padding: 20rpx 40rpx;
-    color: #999;
-    display: flex;
-    align-content: center;
-    justify-items: center;
-    .iconBox {
-      width: 40rpx;
-    }
-    .text {
-      margin-left: 20rpx;
-      &.active {
-        color: #00B760;
-      }
-    }
-  }
-  .popup-upload {
-    // display: flex;
-    // align-items: center;
-    // justify-content: center;
-    // flex-direction: column;
-    // width: 70%;
-    width: 80vw;
-    font-size: .75em;
-    color: #999;
-    padding: 40rpx;
-    &-box {
-      width: 200rpx;
-      height: 200rpx;
-      text-align: center;
-      line-height: 200rpx;
-      border: 4rpx solid #ddd;
-      border-radius: 8rpx;
-      margin: 0 auto;
-    }
-  }
-  .popup-actions {
-    padding: 60rpx;
-    .default {
-      background: #00B760;
-      color: #DDD;
-      font-size: .9em;
-    }
-  }
-}
-</style>

+ 0 - 68
pagesA/editPassword/index.vue

@@ -1,68 +0,0 @@
-<template>
-	<view style="padding: 30rpx;">
-		<uni-forms ref="formRef" :modelValue="formData" :rules="formRules" validateTrigger="bind" label-width="80px" label-align="right" label-position="left">
-			<uni-forms-item name="password" label="新密码" required>
-				<uni-easyinput v-model="formData.password" type="password" placeholder="请输入新密码"></uni-easyinput>
-			</uni-forms-item>
-			<uni-forms-item name="passwordConfirm" label="二次确认" required>
-				<uni-easyinput v-model="formData.passwordConfirm" type="password" placeholder="请再次输入新密码"></uni-easyinput>
-			</uni-forms-item>
-		</uni-forms>
-
-		<button class="send-button" @tap="handleSubmit">提 交</button>
-	</view>
-</template>
-
-<script setup>
-import { ref, unref } from 'vue'
-import { password } from '@/utils/validate'
-import { userStore } from '@/store/user'
-import { entUpdatePassword } from '@/api/enterprise'
-
-const user = userStore()
-const formRef = ref(null)
-const formData = ref({
-	id: user?.userInfo?.id,
-	password: null,
-	passwordConfirm: null
-})
-const formRules = {
-	password,
-	passwordConfirm: {
-		rules: [
-			{ required: true, errorMessage: '请再次输入密码' },
-			{ 
-				validateFunction: function(rule, value, data, callback) {
-					if (value !== data.password) callback('两次输入的密码不一致')
-					return true
-				}
-			}
-		]
-	}
-}
-
-// 提交
-const handleSubmit = async () => {
-	const valid = await unref(formRef).validate()
-	if (!valid) return
-
-	uni.showLoading({ title: '提交中' })
-	try {
-		await entUpdatePassword(formData.value)
-		uni.hideLoading()
-		uni.showToast({
-			title: '修改成功',
-			icon: 'success'
-		})
-		setTimeout(() => {
-			uni.navigateBack({ delta: 1 })
-		}, 1000)
-	} catch {
-		uni.hideLoading()
-	}
-}
-</script>
-
-<style scoped lang="scss">
-
-</style>

+ 0 - 107
pagesA/forgotPassword/index.vue

@@ -1,107 +0,0 @@
-<template>
-	<view style="padding: 30rpx;">
-		<uni-forms ref="formRef" :modelValue="formData" :rules="formRules" validateTrigger="bind" label-width="80px" label-align="right" label-position="left">
-			<uni-forms-item name="email" label="企业邮箱" required>
-				<uni-easyinput v-model="formData.email" placeholder="请输入企业邮箱"></uni-easyinput>
-			</uni-forms-item>
-			<uni-forms-item name="code" label="验证码" required>
-				<uni-easyinput v-model="formData.code" :inputBorder="false" placeholder="请输入邮箱验证码">
-					<template v-slot:right>
-            <button class="login-code" @tap.stop="handleCode">
-              {{ getSmsTimer('resetPassword') }}
-            </button>
-          </template>
-				</uni-easyinput>
-			</uni-forms-item>
-			<uni-forms-item name="password" label="新密码" required>
-				<uni-easyinput v-model="formData.password" type="password" placeholder="请输入新密码"></uni-easyinput>
-			</uni-forms-item>
-			<uni-forms-item name="passwordConfirm" label="二次确认" required>
-				<uni-easyinput v-model="formData.passwordConfirm" type="password" placeholder="请再次输入新密码"></uni-easyinput>
-			</uni-forms-item>
-		</uni-forms>
-
-		<button class="send-button" @tap="handleSubmit">提 交</button>
-	</view>
-</template>
-
-<script setup>
-import { ref, unref } from 'vue'
-import { password, emailRequired } from '@/utils/validate'
-import { resetPassword } from '@/api/enterprise'
-import { getEmailCode, getSmsTimer } from '@/utils/code'
-
-const formRef = ref(null)
-const formData = ref({
-	email: null,
-	code: null,
-	password: null,
-	passwordConfirm: null
-})
-const formRules = {
-	email: emailRequired,
-	code: {
-		rules: [
-			{ required: true, errorMessage: '请输入邮箱验证码' },
-		]
-	},
-	password,
-	passwordConfirm: {
-		rules: [
-			{ required: true, errorMessage: '请再次输入密码' },
-			{ 
-				validateFunction: function(rule, value, data, callback) {
-					if (value !== data.password) callback('两次输入的密码不一致')
-					return true
-				}
-			}
-		]
-	}
-}
-
-// 获取邮箱验证码
-const handleCode = async () => {
-  if (!formData.value.email) {
-    uni.showToast({
-      title: '请输入您的企业邮箱',
-      icon: 'none',
-      duration: 2000
-    })
-    return
-  }
-	getEmailCode('resetPassword', formData.value.email)
-}
-
-// 提交
-const handleSubmit = async () => {
-	const valid = await unref(formRef).validate()
-	if (!valid) return
-
-	uni.showLoading({ title: '提交中' })
-	try {
-		await resetPassword(formData.value)
-		uni.hideLoading()
-		uni.showToast({
-			title: '操作成功',
-			icon: 'success'
-		})
-		setTimeout(() => {
-			uni.navigateBack({ delta: 1 })
-		}, 1000)
-	} catch {
-		uni.hideLoading()
-	}
-}
-</script>
-
-<style scoped lang="scss">
-.login-code {
-  width: 73px;
-  min-width: 73px;
-  color: #00B760;
-  text-align: center; 
-  font-size: 12px; 
-  cursor: pointer;
-  padding: 0;
-}
-</style>

+ 0 - 68
pagesA/interview/attended.vue

@@ -1,68 +0,0 @@
-<template>
-	<view style="padding: 30rpx;">
-		<uni-forms ref="formRef" :modelValue="formData" :rules="formRules" validateTrigger="bind" label-width="80px" label-align="right" label-position="left">
-			<uni-forms-item name="reason" label="爽约原因" required>
-				<uni-easyinput v-model="formData.reason" type="textarea" placeholder="请输入爽约原因"></uni-easyinput>
-			</uni-forms-item>
-		</uni-forms>
-		<button class="send-button" @tap="handleSubmit">提 交</button>
-	</view>
-</template>
-
-<script setup>
-import { ref, unref } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import { noAttendInterviewInvite } from '@/api/interview'
-
-const formRef = ref(null)
-const formData = ref({
-	id: null,
-	reason: null
-})
-const formRules = {
-	reason: {
-		rules: [{ required: true, errorMessage: '请输入爽约原因' }]
-	}
-}
-
-onLoad(async (options) => {
-	const { id } = options
-	if (!id) {
-		uni.showToast({
-			title: 'ID缺失',
-			icon: 'none'
-		})
-		setTimeout(() => {
-			uni.navigateBack({ delta: 1 })
-		}, 1000)
-		return
-	}
-
-	formData.value.id = id
-})
-
-// 提交
-const handleSubmit = async () => {
-	const valid = await unref(formRef).validate()
-	if (!valid) return
-
-	uni.showLoading({ title: '提交中' })
-	try {
-		await noAttendInterviewInvite(formData.value)
-		uni.hideLoading()
-		uni.showToast({
-			title: '提交成功',
-			icon: 'success'
-		})
-		setTimeout(() => {
-			uni.navigateBack({ delta: 1 })
-		}, 1000)
-	} catch {
-		uni.hideLoading()
-	}
-}
-</script>
-
-<style scoped lang="scss">
-
-</style>

+ 0 - 68
pagesA/interview/cancel.vue

@@ -1,68 +0,0 @@
-<template>
-	<view style="padding: 30rpx;">
-		<uni-forms ref="formRef" :modelValue="formData" :rules="formRules" validateTrigger="bind" label-width="80px" label-align="right" label-position="left">
-			<uni-forms-item name="reason" label="取消原因" required>
-				<uni-easyinput v-model="formData.reason" type="textarea" placeholder="请输入取消原因"></uni-easyinput>
-			</uni-forms-item>
-		</uni-forms>
-		<button class="send-button" @tap="handleSubmit">提 交</button>
-	</view>
-</template>
-
-<script setup>
-import { ref, unref } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import { cancelInterviewInvite } from '@/api/interview'
-
-const formRef = ref(null)
-const formData = ref({
-	id: null,
-	reason: null
-})
-const formRules = {
-	reason: {
-		rules: [{ required: true, errorMessage: '请输入取消原因' }]
-	}
-}
-
-onLoad(async (options) => {
-	const { id } = options
-	if (!id) {
-		uni.showToast({
-			title: 'ID缺失',
-			icon: 'none'
-		})
-		setTimeout(() => {
-			uni.navigateBack({ delta: 1 })
-		}, 1000)
-		return
-	}
-
-	formData.value.id = id
-})
-
-// 提交
-const handleSubmit = async () => {
-	const valid = await unref(formRef).validate()
-	if (!valid) return
-
-	uni.showLoading({ title: '提交中' })
-	try {
-		await cancelInterviewInvite(formData.value)
-		uni.hideLoading()
-		uni.showToast({
-			title: '提交成功',
-			icon: 'success'
-		})
-		setTimeout(() => {
-			uni.navigateBack({ delta: 1 })
-		}, 1000)
-	} catch {
-		uni.hideLoading()
-	}
-}
-</script>
-
-<style scoped lang="scss">
-
-</style>

+ 0 - 270
pagesA/interview/components/item.vue

@@ -1,270 +0,0 @@
-<template>
-	<view>
-		<view v-for="(val, index) in items" :key="index" class="mList default-border">
-			<!-- 基本信息 -->
-			<view class="d-flex align-center">
-				<view class="user-avatar">
-					<image class="user-avatar-img" :src="getUserAvatar(val.person?.avatar, val.person?.sex)" mode="scaleToFill"></image>
-					<image class="user-avatar-sex" :src="val?.person?.sex ? val?.person?.sex === '1' ? '/static/img/man.png' : '/static/img/female.png' : ''" alt="" mode="scaleToFill" />
-				</view>
-				<view style="flex: 1; margin-left: 10px;">
-					<view class="d-flex justify-space-between align-center">
-						<view class="font-size-18 default-text-color">{{ val.person?.name }}</view>
-            <view :style="{'color': colorData[val.status]}">
-              {{ val.status ? statusList.find(i => i.value === val.status)?.label : '' }}
-            </view>
-					</view>
-				</view>
-			</view>
-
-			<view class="ss-m-t-15 color-999">
-				<view>
-					投递职位:
-					<image v-if="val.jobFairId" src="/static/svg/jobFair.svg" style="width: 15px; height: 15px;"></image>
-					{{ formatName(val.job?.name) }}
-				</view>
-        <view>联系电话:{{ val.person?.phone ?? '未填写' }}</view>
-				<view>面试时间:{{ timesTampChange(val.time, 'Y-M-D h:m') }}</view>
-				<view v-if="val.status === '4'">反馈内容:{{ val.evaluate }}</view>
-				<view v-if="val.status === '5' || val.status === '99'">{{ val.status === '5' ? '爽约' : '取消' }}原因:{{ val.reason }}</view>
-			</view>
-
-			<view class="sub-li-bottom ss-m-t-20">
-        <template v-if="val.job?.status !== '1'" >
-          <view v-if="editStatus.indexOf(val.status) !== -1" class="sub-li-bottom-item color-primary" @tap.stop="handleActionClick('edit', val)">修改面试</view>
-          <view v-if="againStatus.indexOf(val.status) !== -1" class="sub-li-bottom-item color-primary" @tap.stop="handleActionClick('edit', val)">重新邀约</view>
-        </template>
-        <view v-if="val.status === '1'" class="sub-li-bottom-item color-primary" @click="handleActionClick('completed', val)">完成面试</view>
-        <view v-if="val.status === '3'" class="sub-li-bottom-item color-primary" @click="handleActionClick('feedback', val)">填写反馈</view>
-				<view 
-					class="sub-li-bottom-item d-flex align-center justify-center" 
-					@tap.stop="handleLoadMore(val)" 
-					:style="{'color': val?.job?.status === '1' || !actionItems(val)?.length ? '#ccc' : '#00B760'}"
-				>
-					<view>更多操作</view>
-					<uni-icons type="list" class="ss-m-l-10" size="20" :color="val?.job?.status === '1' || !actionItems(val)?.length ? '#ccc' : '#00B760'"></uni-icons>
-				</view>
-			</view>
-		</view>
-
-
-		<!-- 更多操作 -->
-		<uni-popup ref="popup" type="bottom" :mask-click="true">
-      <view class="actions" v-if="itemData && Object.keys(itemData).length">
-				<view
-					class="action-item"
-					v-for="(val, index) in actionItems(itemData)" 
-					:key="index"
-					@tap.stop="handleActionClick(val.value, itemData)"
-				>{{ val.title }}</view>
-			</view>
-      <button class="big-cancel-button" @tap.stop="handleClosePopup">取消</button>
-    </uni-popup>
-
-    <!-- 完成面试 -->
-    <uni-popup ref="finishPopup" type="dialog">
-			<uni-popup-dialog 
-        type="warn" 
-        cancelText="取消"
-        confirmText="确定" 
-        title="系统提示" 
-        content="是否确认已完成面试?"
-        @confirm="handleFinishConfirm"
-        @close="handleFinishClose"
-      ></uni-popup-dialog>
-		</uni-popup>
-	</view>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import { timesTampChange } from '@/utils/date'
-import { getUserAvatar } from '@/utils/avatar'
-import { formatName } from '@/utils/getText'
-import { completedInterviewInvite } from '@/api/interview'
-
-const emit = defineEmits(['refresh'])
-const props = defineProps({ items: Array, current: [Number, String], statusList: Array })
-
-const editStatus = ['0'] // 修改面试状态
-const againStatus = ['98', '99'] // 重新邀约状态
-const colorData = {
-  '0': 'orange',
-  '1': 'green',
-  '2': 'green',
-  '3': '#00B760',
-  '4': '#999',
-  '5': '#FE574A',
-  '98': '#FE574A',
-  '99': '#999'
-}
-
-const popup = ref()
-const finishPopup = ref()
-const itemData = ref({})
-
-// 更多操作
-const handleLoadMore = (val) => {
-	if (val?.job?.status === '1') {
-		itemData.value = {}
-		uni.showToast({ title: '职位已关闭,暂无更多操作', icon: 'none' })
-		return
-	}
-	if (!actionItems(val).length) {
-		itemData.value = {}
-		uni.showToast({ title: '暂无更多操作', icon: 'none' })
-		return
-	}
-	itemData.value = val
-	popup.value.open()
-}
-
-// 关闭操作弹窗
-const handleClosePopup = () => {
-	popup.value.close()
-	itemData.value = {}
-}
-
-// 完成面试
-const handleFinishClose = () => {
-  if (actionItems(itemData.value).length && actionItems(itemData.value).find(e => e.value === 'completed')) handleClosePopup()
-  else itemData.value = {}
-  finishPopup.value.close()
-}
-const handleFinishConfirm = async () => {
-  if (!itemData.value || !itemData.value.id) return
-  try {
-    await completedInterviewInvite(itemData.value.id)
-    uni.showToast({ title: '操作成功', icon: 'none' })
-    emit('refresh')
-    handleFinishClose()
-  } catch {
-    handleFinishClose()
-  }
-}
-
-const handleActionClick = (type, val) => {
-  if (val.job?.status === '1' && (type !== 'completed')) {
-    uni.showToast({ title: '职位已关闭', icon: 'none' })
-    return
-  }
-  itemData.value = val
-  // 完成面试
-  if (type === 'completed') {
-    finishPopup.value.open()
-  }
-	// 修改面试、重新邀约
-	if (type === 'edit') {
-		uni.navigateTo({
-			url: '/pagesB/InviteInterview/index?editData=' + encodeURIComponent(JSON.stringify(val))
-		})
-	}
-	// 取消面试、爽约、面试反馈
-	if (['cancel', 'attended', 'feedback'].includes(type)) {
-		uni.navigateTo({
-			url: `/pagesA/interview/${type}?id=${val.id}`
-		})
-	}
-	popup.value.close()
-}
-
-const obj = {
-  '0': [1],
-  '1': [4, 1, 3],
-  '2': [3]
-}
-const actions = ref([
-  { title: '完成面试', value: 'completed' },
-  { title: '取消面试', value: 'cancel' },
-  { title: '填写反馈', value: 'feedback' },
-  { title: '爽约', value: 'attended' },
-  { title: '修改面试', value: 'edit' }
-])
-const actionItems = (item) => {
-  const status = item?.status
-  const jobClosed = item.job?.status === '1'
-  const type = jobClosed && obj[status] ? [0] : obj[status] // 职位已关闭只能操作完成面试
-  if (!type || !type.length) return []
-  let data = type.map(e => actions.value[e])
-  return data
-}
-</script>
-
-<style scoped lang="scss">
-.mList {
-	border-radius: 12px;
-	box-shadow: 1px 2px 12px rgba(0, 0, 0, 0.17);
-	margin: 0 30rpx 20rpx 30rpx;
-	padding: 30rpx;
-	background-color: #fbfbfb;
-	font-size: 28rpx;
-	&:first-child {
-		margin-top: 20rpx;
-	}
-}
-.user-avatar {
-	position: relative;
-	&-img {
-		width: 45px;
-		height: 45px;
-		border-radius: 50%;
-	}
-	&-sex {
-		position: absolute;
-		right: 0;
-		bottom: 2px;
-		width: 20px;
-		height: 20px;
-		background-color: #fff;
-		border-radius: 50%;
-	}
-}
-.action {
-  font-size: 28rpx;
-	&-item {
-		text-align: center;
-		width: 90vw;
-		border-bottom: 1px solid #eee;
-		height:44px;
-		line-height: 44px;
-		margin: 0 auto;
-		color: #00B760;
-		background-color: #fff !important;
-		&:first-child {
-			border-radius: 5px 5px 0 0;
-		}
-		&:last-child {
-			border-radius: 0 0 5px 5px;
-			border-bottom: none;
-		}
-	}
-}
-.big-cancel-button {
-  width: 90vw;
-  height:44px;
-  line-height: 44px;
-  margin: 10px auto;
-	color: #fe574a;
-  background-color: #fff !important;
-  font-size: 28rpx;
-}
-.sub-li-bottom {
-  display: flex;
-	justify-content: space-between;
-	// align-items: flex-end;
-  margin-top: 10px;
-  font-size: 13px;
-	&-item {
-		width: 50%;
-		height: 35px;
-		line-height: 35px;
-		text-align: center;
-		margin-right: 15px;
-		background-color: #f7f8fa;
-		border-radius: 4px;
-		&:nth-child(2) {
-			margin-right: 0;
-		}
-	}
-}
-</style>

+ 0 - 68
pagesA/interview/feedback.vue

@@ -1,68 +0,0 @@
-<template>
-	<view style="padding: 30rpx;">
-		<uni-forms ref="formRef" :modelValue="formData" :rules="formRules" validateTrigger="bind" label-width="80px" label-align="right" label-position="left">
-			<uni-forms-item name="evaluate" label="反馈内容" required>
-				<uni-easyinput v-model="formData.evaluate" type="textarea" placeholder="请输入反馈内容"></uni-easyinput>
-			</uni-forms-item>
-		</uni-forms>
-		<button class="send-button" @tap="handleSubmit">提 交</button>
-	</view>
-</template>
-
-<script setup>
-import { ref, unref } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import { feedbackInterviewInvite } from '@/api/interview'
-
-const formRef = ref(null)
-const formData = ref({
-	id: null,
-	evaluate: null
-})
-const formRules = {
-	evaluate: {
-		rules: [{ required: true, errorMessage: '请输入反馈内容' }]
-	}
-}
-
-onLoad(async (options) => {
-	const { id } = options
-	if (!id) {
-		uni.showToast({
-			title: 'ID缺失',
-			icon: 'none'
-		})
-		setTimeout(() => {
-			uni.navigateBack({ delta: 1 })
-		}, 1000)
-		return
-	}
-
-	formData.value.id = id
-})
-
-// 提交
-const handleSubmit = async () => {
-	const valid = await unref(formRef).validate()
-	if (!valid) return
-
-	uni.showLoading({ title: '提交中' })
-	try {
-		await feedbackInterviewInvite(formData.value)
-		uni.hideLoading()
-		uni.showToast({
-			title: '提交成功',
-			icon: 'success'
-		})
-		setTimeout(() => {
-			uni.navigateBack({ delta: 1 })
-		}, 1000)
-	} catch {
-		uni.hideLoading()
-	}
-}
-</script>
-
-<style scoped lang="scss">
-
-</style>

+ 0 - 166
pagesA/interview/index.vue

@@ -1,166 +0,0 @@
-<template>
-  <view class="box defaultBgc">
-    <view style="background-color: #fff;">
-      <uni-segmented-control 
-        :current="current"
-        :values="tabList.map(e => e.label)"
-        @clickItem="changeControl"
-        styleType="text"
-        activeColor="#00B760"
-      ></uni-segmented-control>
-
-      <!-- 条件搜索 -->
-      <view style="margin: 20rpx;">
-        <uni-data-select 
-          v-model="query.jobId" 
-          :clear="true" 
-          :localdata="jobList" 
-          @change="handleChangeJob" 
-          placeholder="招聘职位"
-			></uni-data-select>
-      </view>
-    </view>
-
-    <scroll-view class="scrollBox" :scroll-y="true" @scrolltolower="loadingMore" style="position:relative;">
-			<CardItem v-if="items?.length" :items="items" :statusList="tabList" @refresh="handleRefresh" />
-			<uni-load-more :status="more" />
-		</scroll-view>
-  </view>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import CardItem from './components/item.vue'
-import { getInterviewInvitePage } from '@/api/interview'
-import { getJobAdvertised } from '@/api/search'
-import { onShow, onLoad } from '@dcloudio/uni-app'
-import { getDict } from '@/hooks/useDictionaries'
-import { formatName } from '@/utils/getText'
-
-const current = ref(0)
-const tabList = ref([])
-const more = ref('more')
-const total = ref(0)
-const items = ref([])
-const query = ref({
-  pageNo: 1,
-  pageSize: 10,
-  status: null,
-  jobId: null
-})
-
-// 职位列表
-const jobList = ref([])
-const getJobList = async () => {
-  const { data } = await getJobAdvertised({ exTime: 0 })
-  if (data.length) {
-    jobList.value = data.map(e => {
-      return { text: `${formatName(e.name)}_${e.status === '1' ? '已关闭' : '招聘中'}`, value: e.id }
-    })
-  }
-}
-
-onLoad(() => {
-  getDict('menduner_interview_invite_status').then(({ data }) => {
-    tabList.value = data.data ?? []
-
-    if (!tabList.value.length) return
-    query.value.pageNo = 1
-    getList()
-  })
-  getJobList()
-})
-
-// 获取面试列表
-const getList = async () => {
-  more.value = 'loading'
-
-  query.value.status = tabList.value[current.value].value
-  try {
-    const { data } = await getInterviewInvitePage(query.value)
-    const { list, total: number } = data
-
-    if (!list.length) {
-      more.value = 'noMore'
-      return
-    }
-
-    total.value = number
-    items.value = items.value.concat(list)
-
-    if (items.value.length === +number) {
-      more.value = 'noMore'
-      return
-    }
-  } catch {
-    query.value.pageNo--
-    more.value = 'more'
-  }
-}
-
-onShow(() => {
-  if (!tabList.value.length) return
-  items.value = []
-  query.value.pageNo = 1
-  getList()
-})
-
-// 选择招聘中职位
-const handleChangeJob = () => {
-	query.value.pageNo = 1
-	items.value = []
-	total.value = 0
-	getList()
-}
-
-const handleRefresh = () => {
-  items.value = []
-  total.value = 0
-  query.value.pageNo = 1
-  getList()
-}
-
-const changeControl = (e) => {
-  current.value = e.currentIndex
-  handleRefresh()
-}
-
-// 加载更多
-const loadingMore = () => {
-	if (more.value === 'noMore') return
-  more.value = 'loading'
-  query.value.pageNo++
-	getList()
-}
-</script>
-
-<style scoped lang="scss">
-.box {
-  height: 100vh;
-  overflow: hidden;
-  box-sizing: border-box;
-  display: flex;
-  flex-direction: column;
-}
-.scrollBox{
-	flex: 1;
-  padding-bottom: 24rpx;
-  box-sizing: border-box;
-	height: 0 !important;
-}
-:deep(.segmented-control) {
-	overflow: auto !important;
-}
-:deep(.segmented-control__item) {
-	white-space: nowrap !important;
-	padding: 0 20rpx;
-}
-:deep(.uni-select__selector-item) {
-	display: block !important;
-	text-align: left !important;
-	max-width: 100% !important;
-	white-space: nowrap !important;
-	text-overflow: ellipsis !important;
-	overflow: hidden !important;
-}
-</style>

+ 0 - 186
pagesA/resume/index.vue

@@ -1,186 +0,0 @@
-<template>
-  <view class="box defaultBgc">
-    <view style="background-color: #fff;">
-      <uni-segmented-control 
-        :current="current"
-        :values="tabList.map(e => e.label)"
-        @clickItem="changeControl"
-        styleType="text"
-        activeColor="#00B760"
-      ></uni-segmented-control>
-
-      <!-- 条件搜索 -->
-      <uni-search-bar
-        v-model="query.name"
-        radius="5"
-        placeholder="投递人姓名"
-        cancelButton="none"
-        :focus="false"
-				@clear="handleSearch('name', null)"
-        @confirm="handleSearch('name', query.name)"
-      ></uni-search-bar>
-      <view style="padding: 0 10px;">
-        <FilterList :list="filterList" idValue="label" labelWidth="93%" :paddingBottom="10" @change="handleSearch" />
-      </view>
-    </view>
-
-    <scroll-view class="scrollBox" :scroll-y="true" @scrolltolower="loadingMore" style="position:relative;">
-			<CardItem v-if="items?.length" :items="items" :current="tabList[current].value" @refresh="handleRefresh" />
-			<uni-load-more :status="more" />
-		</scroll-view>
-  </view>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import { timesTampChange } from '@/utils/date'
-import { dealDictObjData } from '@/utils/position'
-import CardItem from './item.vue'
-import FilterList from '@/components/FilterList'
-import { getInterviewInvitePage } from '@/api/interview'
-import { getPersonCvPage, personCvUnfitPage } from '@/api/resume'
-import { getJobFairList } from '@/api/jobFair'
-import { getJobAdvertised } from '@/api/search'
-import { onLoad } from '@dcloudio/uni-app'
-
-const filterList = ref([
-  { label: '投递职位',key: 'jobId', dataLabel: 'name', dataValue: 'id', api: getJobAdvertised, isFormatText: true },
-  { label: '招聘会', key: 'jobFairId' },
-  { label: '最高学历', dictType: 'menduner_education_type', key: 'eduType' },
-  { label: '工作经验', dictType: 'menduner_exp_type', key: 'expType' },
-  // { label: '求职状态', dictType: 'menduner_job_seek_status', key: 'jobStatus' }
-])
-
-const current = ref(0)
-const tabList = ref([
-  { label: '投递简历', value: 0, api: getPersonCvPage, status: null },
-  { label: '已邀约', value: 1, api: getInterviewInvitePage, status: '0' },
-  { label: '已入职', value: 2, api: getInterviewInvitePage, status: '1' },
-  { label: '已结算', value: 3, api: getInterviewInvitePage, status: '2' },
-  { label: '不合适', value: 4, api: personCvUnfitPage },
-])
-const more = ref('more')
-const total = ref(0)
-const items = ref([])
-const query = ref({
-  pageNo: 1,
-  pageSize: 10,
-  type: null,
-  status: null,
-  name: null
-})
-
-// 获取牛人列表
-const getList = async () => {
-  more.value = 'loading'
-
-  const api = tabList.value[current.value].api
-  if (current.value !== 0) {
-    query.value.conversationStatus = tabList.value[current.value].status
-    delete query.value.status
-    delete query.value.type
-  }
-
-  try {
-    const { data } = await api(query.value)
-    const { list, total: number } = data
-
-    if (!list.length) {
-      more.value = 'noMore'
-      return
-    }
-
-    total.value = number
-    const arr = list.map(e => {
-      let obj = e
-      if (e.person) obj.person = Object.assign(e.person, dealDictObjData({}, e.person))
-      obj.job = Object.assign(e.job, dealDictObjData({}, e.job))
-      obj.createTime = timesTampChange(e.createTime, 'Y-M-D h:m')
-      return obj
-    })
-    items.value = items.value.concat(arr)
-
-    if (items.value.length === +number) {
-      more.value = 'noMore'
-      return
-    }
-  } catch {
-    query.value.pageNo--
-    more.value = 'more'
-  }
-}
-
-onLoad(async (options) => {
-  const jobFairList = []
-  // 招聘会列表
-  try {
-    const { data } = await getJobFairList()
-    jobFairList = data.map(e => ({ label: e.title.replace(/<\/?p[^>]*>/gi, ''), value: e.id }))
-  } catch {}
-
-  if (options?.jobId) {
-    query.value.jobId = options.jobId
-    const item = filterList.value.find(e => e.key === 'jobId')
-    item.value = options.jobId
-    item.name = decodeURIComponent(options.jobName)
-  }
-  if (options?.jobFairId) {
-    query.value.jobFairId = options.jobFairId
-    const item = filterList.value.find(e => e.key === 'jobFairId')
-    item.items = jobFairList
-    // 招聘会存在才添加其参数
-    if (jobFairList.find(k => k.id === options.jobFairId)) {
-      item.value = options.jobFairId
-      item.name = decodeURIComponent(options.jobFairName)
-    }
-    
-  }
-  query.value.pageNo = 1
-  getList()
-})
-
-const handleSearch = (key, value) => {
-	query.value.pageNo = 1
-	query.value[key] = value
-
-	items.value = []
-	total.value = 0
-	getList()
-}
-
-const handleRefresh = () => {
-  items.value = []
-  total.value = 0
-  query.value.pageNo = 1
-  getList()
-}
-
-const changeControl = (e) => {
-  current.value = e.currentIndex
-  handleRefresh()
-}
-
-// 加载更多
-const loadingMore = () => {
-	if (more.value === 'noMore') return
-  more.value = 'loading'
-  query.value.pageNo++
-	getList()
-}
-</script>
-
-<style scoped lang="scss">
-.box {
-  height: 100vh;
-  overflow: hidden;
-  box-sizing: border-box;
-  display: flex;
-  flex-direction: column;
-}
-.scrollBox{
-	flex: 1;
-  padding-bottom: 24rpx;
-  box-sizing: border-box;
-	height: 0 !important;
-}
-</style>

+ 0 - 406
pagesA/resume/item.vue

@@ -1,406 +0,0 @@
-<template>
-	<view>
-		<view v-for="(val, index) in items" :key="index" @tap.stop="handleDetail(val)" class="mList default-border">
-			<!-- 基本信息 -->
-			<view class="d-flex align-center">
-				<view class="user-avatar">
-					<image class="user-avatar-img" :src="getUserAvatar(val.person?.avatar, val.person?.sex)" mode="scaleToFill"></image>
-					<image class="user-avatar-sex" :src="val?.person?.sex ? val?.person?.sex === '1' ? '/static/img/man.png' : '/static/img/female.png' : ''" alt="" mode="scaleToFill" />
-				</view>
-				<view style="flex: 1; margin-left: 10px;">
-					<view class="d-flex justify-space-between align-center">
-						<view class="font-size-18 default-text-color">{{ val.person?.name }}</view>
-						<view v-if="current !== 4">
-							<span v-if="current === 0" :style="{'color': val.status && val.status === '0' ? '#fb8c00' : '#00B760'}">
-								{{ val.status && val.status === '0' ? '未查看' : '已查看' }}
-							</span>
-        			<span v-else class="color-999">{{ val.status ? statusList.find(i => i.value === val.status)?.label : '' }}</span>
-						</view>
-					</view>
-					<view class="ss-m-t-10">
-						<span 
-							class="color-999"
-							v-for="(key, index) in desc" 
-							:key="index"
-						>
-							{{ val.person?.[key] }}
-							<span v-if="index !== desc.length - 1 && val.person?.[key]" class="ss-m-x-10">|</span>
-						</span>
-					</view>
-				</view>
-			</view>
-
-			<view class="ss-m-t-15 color-999">
-				<view>
-					投递职位:
-					<image v-if="val.jobFairId" src="/static/svg/jobFair.svg" style="width: 15px; height: 15px;"></image>
-					{{ formatName(val.job?.name) }}
-				</view>
-				<view>操作时间:{{ timesTampChange(val.createTime) }}</view>
-			</view>
-
-			<view class="sub-li-bottom ss-m-t-20">
-				<view
-					class="sub-li-bottom-item color-primary"
-					v-if="(props.current === 0 && val.url) || (props.current !== 0 && val?.cvRel && val?.cvRel?.url)"
-					@tap.stop="handlePreview(val)"
-				>查看/下载附件</view>
-				<view 
-					class="sub-li-bottom-item d-flex align-center justify-center" 
-					@tap.stop="handleLoadMore(val)" 
-					:style="{'color': !actionItems(val)?.length ? '#ccc' : '#00B760'}"
-				>
-					<view>更多操作</view>
-					<uni-icons type="list" class="ss-m-l-10" size="20" :color="!actionItems(val)?.length ? '#ccc' : '#00B760'"></uni-icons>
-				</view>
-			</view>
-		</view>
-
-
-		<!-- 更多操作 -->
-		<uni-popup ref="popup" type="bottom" :mask-click="true">
-      <view class="actions" v-if="itemData && Object.keys(itemData).length">
-				<view
-					class="action-item"
-					v-for="(val, index) in actionItems(itemData)" 
-					:key="index"
-					:style="{'color': val?.disabled ? '#ccc' : '#00B760'}"
-					@tap.stop="val.click(itemData)"
-				>{{ val.title }}</view>
-			</view>
-      <button class="big-cancel-button" @tap.stop="handleClosePopup">取消</button>
-    </uni-popup>
-	</view>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import { timesTampChange } from '@/utils/date'
-import { getUserAvatar } from '@/utils/avatar'
-import { formatName } from '@/utils/getText'
-import { preview } from '@/utils/preview'
-import { getDict } from '@/hooks/useDictionaries'
-import { userStore } from '@/store/user'
-import { defaultText, talkToUser } from '@/hooks/useIM'
-import { joinToTalentPool, joinEliminate, personCvUnfitCancel, personEntryByEnterprise, hireJobCvRelSettlement, personJobCvLook } from '@/api/resume'
-
-const emit = defineEmits(['refresh'])
-const props = defineProps({ items: Array, current: [Number, String] })
-
-const user = userStore()
-const statusList = ref([])
-getDict('menduner_interview_invite_status').then(({ data }) => {
-	statusList.value = data.data || []
-})
-
-const desc = ['jobStatusName', 'eduName', 'expName']
-const popup = ref()
-const itemData = ref({})
-
-// 查看在线简历
-const handleDetail = async (val) => {
-	const id = props.current === 0 ? val.id : val?.cvRel?.id
-	if (!val.userId || !id) {
-		uni.showToast({ title: '用户ID不存在', icon: 'none' })
-		return
-	}
-	
-	try {
-		const {data } = await personJobCvLook(id)
-		if (data) emit('refresh')
-	} catch {}
-	uni.navigateTo({
-		url: `/pagesB/personnelDetails/index?id=${val.userId}&type=1`
-	})
-}
-
-// 查看附件
-const handlePreview = async (val) => {
-	// 效验企业是否有查看简历次数
-	const info = await user.getUserInfos()
-	if (info?.entitlement?.lookCvCount <= 0) {
-		uni.showToast({ title: '查看简历次数已用完,请联系门墩儿管理员', icon: 'none', duration: 2000 })
-		return
-	}
-
-	const id = props.current === 0 ? val.id : val?.cvRel?.id
-	const url = props.current === 0 ? val.url : val?.cvRel?.url
-	if (!val.userId || !id) {
-		uni.showToast({ title: '用户ID不存在', icon: 'none' })
-		return
-	}
-	if (!url) {
-		uni.showToast({ title: '附件地址不存在', icon: 'none' })
-		return
-	}
-	try {
-		const {data } = await personJobCvLook(id)
-		if (data) emit('refresh')
-	} catch {}
-	preview(url)
-}
-
-// 更多操作
-const handleLoadMore = (val) => {
-	if (!actionItems(val).length) {
-		itemData.value = {}
-		uni.showToast({ title: '暂无更多操作', icon: 'none' })
-		return
-	}
-	itemData.value = val
-	popup.value.open()
-}
-
-// 关闭操作弹窗
-const handleClosePopup = () => {
-	popup.value.close()
-	itemData.value = {}
-}
-
-// 加入储备 
-const handleJoinToTalentPool = async (item) => {
-  if (!item.userId) {
-		uni.showToast({ title: '用户ID不存在', icon: 'none' })
-		return
-	}
-  try {
-		await joinToTalentPool(item.userId)
-		uni.showToast({ title: '加入成功', icon: 'none' })
-		handleClosePopup()
-		emit('refresh')
-	} catch {
-		handleClosePopup()
-	}
-}
-
-// 邀请面试
-const handleInterviewInvite = (item) => {
-	if (item?.job?.status === '1') {
-		uni.showToast({ title: '职位已关闭', icon: 'none' })
-		return
-	}
-	if (item.handleStatus) {
-		uni.showToast({ title: '已邀面试', icon: 'none' })
-		return
-	}
-	uni.navigateTo({
-	  url: `/pagesB/InviteInterview/index?id=${item.userId}&jobId=${item.job.id}&jobCvRelId=${item.id}`
-	})
-	handleClosePopup()
-}
-
-// 不合适
-const handleEliminate = async (item) => {
-	if (!item.userId) {
-		uni.showToast({ title: '用户ID不存在', icon: 'none' })
-		return
-	}
-	const query = {
-    bizId: item.id,
-    jobId: item.job.id,
-    userId: item.userId,
-		jobCvRelId: props.current === 0 ? item.id : item?.cvRel?.id,
-    type: props.current === 0 ? '0' : '1' // 投递简历0 已邀约1
-  }
-	// 招聘会职位则带id
-  if (item?.jobFairId) query.jobFairId = item.jobFairId
-  try {
-		await joinEliminate(query)
-		uni.showToast({ title: '操作成功', icon: 'none' })
-		handleClosePopup()
-		emit('refresh')
-	} catch {
-		handleClosePopup()
-	}
-}
-
-// 取消不合适
-const handleCancelEliminate = async (item) => {
-	if (!item.id) {
-		uni.showToast({ title: 'ID不存在', icon: 'none' })
-		return
-	}
-	try {
-		await personCvUnfitCancel(item.id)
-		uni.showToast({ title: '操作成功', icon: 'none' })
-		handleClosePopup()
-		emit('refresh')
-	} catch {
-		handleClosePopup()
-	}
-}
-
-// 立即沟通
-const handleToCommunicate = async (item) => {
-	if (item?.job?.status === '1') {
-		uni.showToast({ title: '职位已关闭', icon: 'none' })
-		return
-	}
-
-	const userId = item.userId
-  if (!userId) return
-  const channel = await talkToUser({ userId, text: defaultText })
-
-	const query = {
-		id: userId,
-		name: item?.person?.name || item?.person?.phone,
-		channelID: channel.channelID,
-		channelType: channel.channelType,
-		avatar: item?.person?.avatar,
-		sex: item?.person?.sex,
-	}
-
-	const queryStr = Object.keys(query).reduce((r, v) => {
-		if (!query[v]) {
-			return r
-		}
-		return r += `${v}=${encodeURIComponent(query[v])}&`
-	}, '?')
-	uni.navigateTo({
-		url: `/pagesA/chart/index${queryStr.slice(0, -1)}`
-  })
-	handleClosePopup()
-}
-
-// 结算
-const handleSettlement = async (item) => {
-	if (!item.id) {
-		uni.showToast({ title: 'ID不存在', icon: 'none' })
-		return
-	}
-	try {
-		await hireJobCvRelSettlement(item.id)
-		uni.showToast({ title: '操作成功', icon: 'none' })
-		handleClosePopup()
-		emit('refresh')
-
-		// 更新账户信息
-		setTimeout(async () => {
-			await user.getAccountInfo()
-		}, 2000)
-	} catch {
-		handleClosePopup()
-	}
-}
-
-// 入职
-const handleEnterByEnterprise = async (item) => {
-	if (!item.id) {
-		uni.showToast({ title: 'ID不存在', icon: 'none' })
-		return
-	}
-	try {
-		await personEntryByEnterprise(item.id)
-		uni.showToast({ title: '操作成功', icon: 'none' })
-		handleClosePopup()
-		emit('refresh')
-	} catch {
-		handleClosePopup()
-	}
-}
-
-const actionItems = (item) => {
-	const jobClosed = item.job.status === '1' || false
-  const arr = []
-  if (props.current === 0) {
-		arr.push(
-			{
-				title: jobClosed ? '邀请面试(职位已关闭)' : item.handleStatus ? '邀请面试(已邀面试)' : '邀请面试',
-				disabled: jobClosed || item.handleStatus,
-				click: handleInterviewInvite
-			},
-			{
-				title: jobClosed ? '立即沟通(职位已关闭)' : '立即沟通',
-				disabled: jobClosed,
-				click: handleToCommunicate
-			},
-		)
-  }
-  if ([0, 1].includes(props.current)) arr.push({ title: '不合适', click: handleEliminate })
-  if (props.current === 4) arr.push({ title: '取消不合适', click: handleCancelEliminate })
-  if (props.current === 2 && item?.job?.hire) arr.push({ title: '结算', click: handleSettlement })
-  if (props.current === 1 && ['3', '4'].includes(item.status)) arr.push({ title: '入职', click: handleEnterByEnterprise })
-	// 面试后才能够加入储备
-  if ([1, 2, 3].includes(props.current) && !item.inTalentPool) arr.push({ title: '加入储备', click: handleJoinToTalentPool })
-  return arr
-}
-</script>
-
-<style scoped lang="scss">
-.mList {
-	border-radius: 12px;
-	box-shadow: 1px 2px 12px rgba(0, 0, 0, 0.17);
-	margin: 0 30rpx 20rpx 30rpx;
-	padding: 30rpx;
-	background-color: #fbfbfb;
-	font-size: 28rpx;
-	&:first-child {
-		margin-top: 20rpx;
-	}
-}
-.user-avatar {
-	position: relative;
-	&-img {
-		width: 45px;
-		height: 45px;
-		border-radius: 50%;
-	}
-	&-sex {
-		position: absolute;
-		right: 0;
-		bottom: 2px;
-		width: 20px;
-		height: 20px;
-		background-color: #fff;
-		border-radius: 50%;
-	}
-}
-.action {
-  font-size: 28rpx;
-	&-item {
-		text-align: center;
-		width: 90vw;
-		border-bottom: 1px solid #eee;
-		height:44px;
-		line-height: 44px;
-		margin: 0 auto;
-		color: #00B760;
-		background-color: #fff !important;
-		&:first-child {
-			border-radius: 5px 5px 0 0;
-		}
-		&:last-child {
-			border-radius: 0 0 5px 5px;
-			border-bottom: none;
-		}
-	}
-}
-.big-cancel-button {
-  width: 90vw;
-  height:44px;
-  line-height: 44px;
-  margin: 10px auto;
-	color: #fe574a;
-  background-color: #fff !important;
-  font-size: 28rpx;
-}
-.sub-li-bottom {
-  display: flex;
-	justify-content: space-between;
-	// align-items: flex-end;
-  margin-top: 10px;
-  font-size: 13px;
-	&-item {
-		width: 50%;
-		height: 35px;
-		line-height: 35px;
-		text-align: center;
-		margin-right: 15px;
-		background-color: #f7f8fa;
-		border-radius: 4px;
-		&:nth-child(2) {
-			margin-right: 0;
-		}
-	}
-}
-</style>

+ 0 - 208
pagesB/CompanyInfoEdit/index.vue

@@ -1,208 +0,0 @@
-<template>
-	<view class="f-straight wrapper">
-		<uni-forms ref="form" :modelValue="formData" :rules="rules" validateTrigger="bind" label-width="90px" label-align="right">
-			<uni-forms-item label="企业LOGO" name="logoUrl" class="f-straight" required>
-        <view style="display: flex;flex-wrap: wrap;">
-          <view class="upload-img" v-if="formData?.logoUrl">
-            <uni-icons size="35" type="clear" color="#fe574a" style="position: absolute;right: -15px; top: -15px; z-index: 9" @click="formData.logoUrl = ''"></uni-icons>
-            <image :src="formData?.logoUrl" mode="contain" style="width: 200rpx;height: 200rpx;" @click="handlePreviewImage"></image>
-          </view>
-          <view v-else class="upload-file" @click="uploadPhotos">
-            <uni-icons type="plusempty" size="50" color="#f1f1f1"></uni-icons>
-          </view>
-        </view>
-			</uni-forms-item>
-			<uni-forms-item label="企业全称" name="name" required>
-        <uni-easyinput v-model="formData.name" placeholder="请输入企业全称" />
-			</uni-forms-item>
-      <uni-forms-item label="展示名称" name="anotherName" required>
-				<uni-easyinput v-model="formData.anotherName" placeholder="请输入对外展示名称" />
-			</uni-forms-item>
-      <uni-forms-item label="企业官网" name="website" clearable>
-        <uni-easyinput v-model="formData.website" placeholder="请输入企业官网" />
-			</uni-forms-item>
-      <uni-forms-item label="联系人" name="contact" clearable>
-        <uni-easyinput v-model="formData.contact" placeholder="请输入联系人" />
-			</uni-forms-item>
-      <uni-forms-item label="联系电话" name="phone" clearable>
-        <uni-easyinput v-model="formData.phone" placeholder="请输入联系电话" />
-			</uni-forms-item>
-      <uni-forms-item label="开业时间" name="openTime">
-        <picker mode="date" :value="formData.openTime" fields="month" @change="e => formData.openTime = e.detail.value">
-          <view class="uni-input ss-m-t-20">{{ formData.openTime || '请选择开业时间' }}</view>
-        </picker>
-        <uni-data-checkbox selectedColor="#00B760" class="ss-m-l-50 ss-m-t-14" multiple v-model="sofar" :localdata="[{ text: '筹备中(如果贵企业正在筹备,请勾选)', value: 1 }]"></uni-data-checkbox>
-			</uni-forms-item>
-			<uni-forms-item label="所在行业" name="industryId" required>
-				<uni-data-picker
-          v-model="formData.industryId"
-          :localdata="dictObj.industryTreeData"
-          :clear-icon="false"
-          popup-title="请选择所在行业"
-          :clear="false"
-          :map="{ text: 'nameCn', value: 'id' }"
-        ></uni-data-picker>
-			</uni-forms-item>
-      <uni-forms-item label="企业规模" name="scale" required>
-				<uni-data-picker
-          v-model="formData.scale"
-          :localdata="dictObj.scale"
-          :clear-icon="false"
-          popup-title="请选择企业规模"
-          :clear="false"
-          :map="{ text: 'label', value: 'value' }"
-        ></uni-data-picker>
-			</uni-forms-item>
-			<uni-forms-item label="企业介绍" name="introduce" required>
-				<uni-easyinput v-model="formData.introduce" type="textarea" placeholder="请输入企业介绍" />
-			</uni-forms-item>
-			<view class="f-horizon-center">
-				<button type="primary" size="default" class="send-button"  @click="submit">提 交</button>
-			</view>
-		</uni-forms>
-	</view>
-</template>
-
-<script setup>
-import { ref, unref } from 'vue'
-import { userStore } from '@/store/user'
-import { dictObj } from '@/utils/position.js'
-import { uploadFile } from '@/api/file'
-import { timesTampChange, convertYearMonthToTimestamp } from '@/utils/date'
-import { updateEnterpriseInfo, updateEnterpriseLogo, getEnterpriseInfo } from '@/api/enterprise'
-
-const form = ref()
-const useUserStore = userStore()
-
-const sofar = ref([])
-const date = new Date()
-const formData = ref({})
-
-// 获取企业信息
-const getInfo = async () => {
-  const { data } = await getEnterpriseInfo()
-  formData.value = data || {
-    logoUrl: '',
-    name: '',
-    anotherName: '',
-    website: '',
-    openTime: '',
-    contact: '',
-    phone: '',
-    industryId: '',
-    scale: '',
-    introduce: ''
-  }
-  if (data.prepare) {
-    sofar.value = [1]
-  }
-  formData.value.openTime = formData.value.openTime ? timesTampChange(data.openTime, 'Y-M') : null
-}
-getInfo()
-
-// 图片预览
-const handlePreviewImage = () => {
-  uni.previewImage({
-    current: 0,
-    urls: [formData.value.logoUrl]
-  })
-}
-
-// 选择头像
-const uploadPhotos = () => {
-  wx.chooseImage({
-    count: 1,
-    sizeType: ['original', 'compressed'],
-    sourceType: ['album', 'camera'],
-    success: function(res){
-      const size = res.tempFiles[0]?.size || 0
-      if (size >= 31457280) {
-        uni.showToast({
-          icon: 'none',
-          title: '头像上传大小不得超过 20MB !',
-          duration: 2000
-        })
-        return
-      }
-      const path = res.tempFilePaths[0]
-      uploadFile(path, 'img').then(res => {
-        formData.value.logoUrl = res.data
-      }).catch(error => {
-        uni.showToast({
-          icon: 'error',
-          title: '图片上传失败!',
-          duration: 2000
-        })
-      })
-    }
-  })
-}
-
-const rules = {
-	logoUrl:{
-		rules: [{required: true, errorMessage: '请上传企业logo' }]
-	},
-	name:{
-		rules: [{required: true, errorMessage: '请输入企业全称' }]
-	},
-  introduce:{
-		rules: [{required: true, errorMessage: '请输入企业介绍' }]
-	},
-	anotherName : {
-		rules: [{required: true, errorMessage: '请选择企业对外展示名称' }]
-	},
-	industryId: {
-		rules: [{required: true, errorMessage: '请选择企业所在行业' }]
-	},
-  scale: {
-		rules: [{required: true, errorMessage: '请选择企业规模' }]
-	}
-}
-
-const submit = async () => {
-  const valid = await unref(form).validate()
-  if (!valid) return
-  
-  formData.value.openTime = formData.value.openTime ? convertYearMonthToTimestamp(formData.value.openTime) : null
-  formData.value.prepare = sofar.value.length ? true : false
-  
-  const { logoUrl, ...rest } = formData.value
-  
-  await updateEnterpriseLogo(logoUrl)
-  await updateEnterpriseInfo(rest)
-
-  uni.showToast({ title: '编辑成功', icon: 'success' })
-  await useUserStore.getUserInfos()
-  getInfo()
-
-  setTimeout(() => {
-		uni.navigateBack({
-			delta: 1
-		})
-	}, 1000)
-}
-</script>
-
-<style lang="less" scoped>
-.wrapper{
-	padding: 15px;
-  padding-top: 30px;
-}
-.upload-img{
-  position: relative;
-  width: 200rpx;
-  height: 200rpx;
-  border: 1px solid #f1f1f1;
-  margin: 10rpx;
-}
-.upload-file{
-  width: 200rpx;
-  height: 200rpx;
-  border: 1px solid #f1f1f1;
-  margin: 10rpx;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  border-radius: 10rpx;
-}
-</style>

+ 0 - 195
pagesB/InviteInterview/index.vue

@@ -1,195 +0,0 @@
-<template>
-	<view style="padding: 30rpx;">
-		<uni-forms ref="formRef" :modelValue="formData" :rules="formRules" validateTrigger="bind" label-width="80px" label-align="right" label-position="left">
-			<uni-forms-item name="time" label="面试时间" required>
-				<uni-datetime-picker
-					v-model="formData.time"
-					type="datetime"
-					:border="true"
-					returnType="timestamp"
-					:hide-second="true"
-					@change="handleDate"
-				 />
-			</uni-forms-item>
-			<uni-forms-item name="jobId" label="招聘职位" required>
-				<view style="max-width: calc(100vw - 110px);">
-          <uni-data-select	v-model="formData.jobId" :disabled="jobDisabled" :localdata="jobList"	@change="handleChangeJob"	placeholder="请选择招聘职位"></uni-data-select>
-        </view>
-			</uni-forms-item>
-			<uni-forms-item name="address" label="面试地点" required>
-				<uni-easyinput v-model="formData.address" placeholder="请输入面试地点"></uni-easyinput>
-			</uni-forms-item>
-			<uni-forms-item name="invitePhone" label="联系电话" required>
-				<uni-easyinput v-model="formData.invitePhone" placeholder="请输入联系电话"></uni-easyinput>
-			</uni-forms-item>
-			<uni-forms-item name="remark" label="备注事项">
-				<uni-easyinput v-model="formData.remark" type="textarea" placeholder="请输入备注事项"></uni-easyinput>
-			</uni-forms-item>
-		</uni-forms>
-		<button class="send-button" @tap="handleSubmit">提 交</button>
-	</view>
-</template>
-
-<script setup>
-import { ref, unref } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import { userStore } from '@/store/user'
-import { mobile } from '@/utils/validate'
-import { getJobAdvertised } from '@/api/new/position'
-import { formatName } from '@/utils/getText'
-import { getInterviewInviteDefaultTime } from '@/utils/date'
-import { saveInterviewInvite } from '@/api/interview'
-import { send } from '@/hooks/useIM'
-
-const formRef = ref(null)
-const useUserStore = userStore()
-const jobDisabled = ref(false)
-const formData = ref({
-	userId: null,
-	address: null,
-	invitePhone: useUserStore?.userInfo?.phone || '',
-	time: getInterviewInviteDefaultTime().timeStamp,
-	jobId: null,
-	remark: null,
-	type: 1
-})
-const formRules = {
-	time: {
-		rules: [{ required: true, errorMessage: '请选择面试时间' }]
-	},
-  invitePhone: mobile,
-	address: {
-		rules: [{ required: true, errorMessage: '请输入面试地点' }]
-	},
-	jobId: {
-		rules: [{ required: true, errorMessage: '请选择邀请面试的职位' }]
-	}
-}
-
-// 职位列表
-const jobList = ref([])
-const getJobList = async (jobId) => {
-  const { data } = await getJobAdvertised({ status: '0', exTime: 0 })
-  jobList.value = data.map(e => {
-    return { text: formatName(e.name), value: e.id, data: e }
-  })
-
-	// 有职位id的则默认选中
-	if (jobId) {
-		formData.value.jobId = jobId
-		formData.value.address = jobList.value.find(item => item.value === jobId)?.data.address
-		jobDisabled.value = true
-	}
-}
-
-const handleChangeJob = (e) => {
-	const job = jobList.value.find(item => item.value === e)
-	if (!job) return
-	formData.value.address = job.data.address
-
-	// 沟通-面试邀请需携带职位信息
-	if (channerl.value && Object.keys(channerl.value).length > 0) formData.value.positionInfo = job
-}
-
-const handleDate = (val) => {
-	const selectedDate = new Date(val)
-  const currentDate = new Date()
-  if (selectedDate < currentDate) {
-		uni.showToast({
-			title: '面试时间不得小于当前时间',
-      icon: 'none',
-			duration: 2000
-    })
-  }
-}
-
-const channerl = ref({})
-onLoad(async (options) => {
-	// 编辑面试、重新邀约
-	if (options?.editData) {
-		const obj = JSON.parse(decodeURIComponent(options.editData))
-		for (let key in formData.value) {
-			formData.value[key] = obj[key]
-		}
-		formData.value.id = obj.id
-		if (obj.jobFairId) formData.value.jobFairId = obj.jobFairId
-		// 有实习时间的则为学生,需传递实习时间
-		if (obj?.practiceStartTime && obj?.practiceEndTime) {
-			formData.value.practiceStartTime = obj.practiceStartTime
-			formData.value.practiceEndTime = obj.practiceEndTime
-		}
-		await getJobList()
-		return
-	}
-
-	// 沟通-面试邀请
-	if (options?.chartData) {
-		const obj = JSON.parse(decodeURIComponent(options.chartData))
-		formData.value.userId = obj.id
-		channerl.value = {
-			channelID: obj.channelID,
-			channelType: obj.channelType
-		}
-		await getJobList()
-		return
-	}
-	
-	if (options?.jobCvRelId) formData.value.jobCvRelId = options.jobCvRelId
-
-	const { id, jobId } = options
-	if (!id) {
-		uni.showToast({
-			title: '缺少人员id',
-			icon: 'none'
-		})
-		setTimeout(() => {
-			uni.navigateBack({ delta: 1 })
-		}, 1000)
-		return
-	}
-
-	formData.value.userId = id
-	await getJobList(jobId)
-})
-
-// 提交
-const handleSubmit = async () => {
-	const valid = await unref(formRef).validate()
-	if (!valid) return
-
-	const selectedDate = new Date(formData.value.time)
-  const currentDate = new Date()
-  if (selectedDate < currentDate) {
-		uni.showToast({
-			title: '面试时间不得小于当前时间',
-      icon: 'none',
-			duration: 2000
-    })
-		return
-  }
-
-	uni.showLoading({ title: '提交中' })
-	try {
-		await saveInterviewInvite(formData.value)
-		
-		// 从沟通过来的需要发消息
-		if (channerl.value && Object.keys(channerl.value).length > 0) send(JSON.stringify(formData.value), channerl.value, 101)
-		
-		uni.hideLoading()
-		uni.showToast({
-			title: '提交成功',
-			icon: 'success'
-		})
-		channerl.value = {}
-		setTimeout(() => {
-			uni.navigateBack({ delta: 1 })
-		}, 1000)
-	} catch {
-		uni.hideLoading()
-	}
-}
-</script>
-
-<style scoped lang="scss">
-
-</style>

+ 0 - 36
pagesB/agreement/CopyrightPolicy.vue

@@ -1,36 +0,0 @@
-<template>
-  <div class="conter">
-    <div class="Protocol">
-      <h1 class="segment">版权政策</h1>
-      <p class="text-color"><span class="text-font">苏州识喜识谊信息科技有限公司(以下称“门墩儿网站”、“本网站”)尊重他人的知识产权,志在提供内容不侵犯他人知识产权的网站。根据《中华人民共和国著作权法》、《信息网络传播权保护条例》、《互联网著作权行政保护办法》等相关法律、法规的规定,门墩儿网站针对网络侵权采取如下版权政策:</span></p>
-      <p class="text-color"><span class="text-font">1. 本网站对网络版权保护尽合理、审慎的义务,在有理由确信存在明显侵犯任何第三人版权的作品时,有权不事先通知并随时删除该涉嫌侵权作品;</span></p>
-      <p class="text-color"><span class="text-font">2. 本网站在接到符合法定要求的版权通知后,将迅速删除涉嫌侵权作品;</span></p>
-      <p class="text-color"><span class="text-font">3. 本网站采取必要的技术措施,尽可能防止相同的侵权作品的再次上传;</span></p>
-      <p class="text-color"><span class="text-font">4.在适当情况下,经本网站决定后,涉嫌一次或多次侵犯他人知识产权、或发布不准确或非法内容的会员或组织(视具体情况而定)的帐号将被禁用或关闭。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">版权侵犯通知</span></h2>
-      <p class="text-color"><span class="text-font">如果您认为门墩儿网站上提供的信息存储空间所上载、传播的任何内容侵犯了您的信息网络传播权或者删除、改变了您的权利管理电子信息的,您可以通过向本网站的邮箱发送邮件,或向本网站版权负责人寄送信件,要求本网站删除该作品或者断开该作品的链接。通知书需由权利人或其合法授权人亲笔签名,若为单位则需加盖单位公章。</span></p>
-      <p class="text-color"><span class="text-font">通知书应当包含下列内容:</span></p>
-      <p class="text-color"><span class="text-font">1. 权利人的姓名(名称)、联系方式、地址、身份证复印件(自然人)、单位登记证明复印件(单位);</span></p>
-      <p class="text-color"><span class="text-font">2. 要求删除或者断开链接的侵权作品的准确名称和网络地址,以便本网站能够发现并初步审核涉嫌侵权作品;</span></p>
-      <p class="text-color"><span class="text-font">3. 认为构成侵权的初步证明材料,包括但不限于对作品享有版权或依法享有信息网络传播权的权属证明等。</span></p>
-      <p class="text-color"><span class="text-font">您应对通知书的真实性负责。若通知书的内容不真实,您将承担由此造成的全部法律责任。因此建议在提交通知书前,先进行法律咨询。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">反驳通知</span></h2>
-      <p class="text-color"><span class="text-font">作品提供者收到本网站转送的通知书后,认为其提供的作品并未侵犯他人权利的,可向本网站提交反通知的书面说明,要求恢复被删除的作品或被断开的作品链接。反通知书需作品提供者或其合法授权人亲笔签名,若为单位则需加盖单位公章。</span></p>
-      <p class="text-color"><span class="text-font">反通知应当包含下列内容:</span></p>
-      <p class="text-color"><span class="text-font">1. 作品提供者的姓名(名称)、联系方式、地址、身份证复印件(自然人)、单位登记证明复印件(单位);</span></p>
-      <p class="text-color"><span class="text-font">2. 要求恢复被删除的作品,或者被断开链接的作品的准确名称和网络地址,以便本网站能够发现并初步审核涉嫌侵权的作品;</span></p>
-      <p class="text-color"><span class="text-font">3. 认为不构成侵权的初步证明材料,包括但不限于对作品享有著作权或依法享有信息网络传播权的权属证明等。</span></p>
-      <p class="text-color"><span class="text-font">作品提供者应对反通知书的真实性负责。若通知书的内容不真实,提供者将承担由此造成的全部法律责任。因此建议在提交反驳通知书前,先进行法律咨询。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">线下版权通知</span></h2>
-      <p class="text-color"><span class="text-font">投诉请邮寄至如下地址:</span></p>
-      <p class="text-color"><span class="text-font">地址:江苏省苏州工业园区林泉街 399 号东南大学国家 大学科技园(苏州)南工院(2#)304 室</span></p>
-      <p class="text-color"><span class="text-font">邮编:215123</span></p>
-      <p class="text-color"><span class="text-font">公司:苏州识喜识谊信息科技有限公司</span></p>
-      <p class="text-color"><span class="text-font">邮箱:services@menduner.com</span></p>
-    </div>
-  </div>
-</template>
-
-<style scoped lang="scss">
-@import '../../static/style/protocol/index.scss';
-</style>

+ 0 - 102
pagesB/agreement/UserBehaviorNorms.vue

@@ -1,102 +0,0 @@
-<template>
-  <div class="conter">
-    <div class="Protocol">
-      <h1 class="segment">用户行为规范</h1>
-      <h2 class="subtitle text-size"><span class="text-font">一、前言</span></h2>
-      <p class="text-color"><span class="text-font">《用户行为规范》(以下简称“本规范”)适用门墩儿招聘所有用户,是《门墩儿招聘用户服务协议》的重要组成部分,两者具有同等法律效力,用户同意或使用门墩儿招聘服务(即《门墩儿招聘用户协议》所提及的门墩儿招聘网页(www.menduner.com)、移动客户端(包括IOS、安卓及已有或未来将新增的任何其他移动客户端)等各类平台或媒介的服务,以下简称“本服务”)的行为即视为同意受到本规范的约束。本协议术语及定义与《门墩儿招聘用户协议》一致。
-        <strong>您应当仔细阅读并遵守本用户协议下的全部内容,特别是涉及免除或者限制我们的责任的条款,此类条款可能以黑体加粗的形式提示您注意。</strong></span></p>
-      <p class="text-color"><span class="text-font">本规范与《门墩儿招聘用户协议》不一致之处(如有),以本规范为准,本规范未提及事宜,以《门墩儿招聘用户协议》中的约定为准。</span></p>
-      <p class="text-color"><span class="text-font">用户(包括求职者用户和招聘者用户)在使用本服务(详情请查阅《门墩儿招聘用户协议》)的过程中,应当遵守宪法和其他适用的法律法规(以下简称“相关法律法规”),包括但不限于《中华人民共和国保守国家秘密法》、《中华人民共和国网络安全法》、《中华人民共和国数据安全法》、《中华人民共和国著作权法》、《中华人民共和国劳动法》、《中华人民共和国劳动合同法》、《中华人民共和国计算机信息系统安全保护条例》、《计算机软件保护条例》、《互联网电子公告服务管理规定》、《网络信息内容生态治理规定》、《信息网络传播权保护条例》、《互联网信息服务管理办法》、《网络信息内容生态治理规定》、《互联网用户账号名称管理规定》等有关计算机及互联网规定的法律法规,以及《中华人民共和国就业促进法》、《就业服务与就业管理规定》、《中华人民共和国广告法》、《中华人民共和国个人信息保护法》、《中华人民共和国民法典》、《互联网广告管理办法》、《网络招聘服务管理规定》等相关法律法规;应当遵循公序良俗,不得损害国家利益、公共利益和他人合法权益。</span></p>
-      <p class="text-color"><span class="text-font">您理解并同意,您须为您的门墩儿招聘账号(包括招聘方用户账号以及求职者用户账号)下的一切行为负责,包括您所发表的任何内容以及由此产生的任何后果。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">二、用户权利</span></h2>
-      <p class="text-color"><span class="text-font">用户在使用本服务期间,有权:</span></p>
-      <p class="text-color"><span class="text-font">1、根据《门墩儿招聘用户协议》和相关法律法规,制作、发布、上传由用户原创或取得了合法授权(含转授权)内容,包括但不限于文字、图片、语音、视频、直播等内容。</span></p>
-      <p class="text-color"><span class="text-font">2、根据《门墩儿招聘用户协议》,在我们的授权范围或门墩儿招聘各类平台或媒介支持的功能范围内,使用本服务。</span></p>
-      <p class="text-color"><span class="text-font">3、向我们提出与本服务有关的意见和建议,以帮助我们更好地向您提供服务。</span></p>
-      <p class="text-color"><span class="text-font">4、对其他用户的违法违规行为、违反本协议条款和规则的行为,与我们联系进行投诉和举报。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">三、用户义务</span></h2>
-      <p class="text-color"><span class="text-font">用户在使用门墩儿招聘服务期间,禁止:</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">1、制作、上传、复制、传送、传播包含下列内容的违法信息:</span></h2>
-      <p class="text-color"><span class="text-font">(1)反对宪法所确定的基本原则的;</span></p>
-      <p class="text-color"><span class="text-font">(2)危害国家安全,泄露国家秘密,颠覆国家政权,破坏国家统一的;</span></p>
-      <p class="text-color"><span class="text-font">(3)损害国家荣誉和利益的;</span></p>
-      <p class="text-color"><span class="text-font">(4)歪曲、丑化、亵渎、否定英雄烈士事迹和精神,以侮辱、诽谤或者其他方式侵害英雄烈士的姓名、肖像、名誉、荣誉的;</span></p>
-      <p class="text-color"><span class="text-font">(5)宣扬恐怖主义、极端主义或者煽动实施恐怖活动、极端主义活动的;</span></p>
-      <p class="text-color"><span class="text-font">(6)煽动民族仇恨、民族歧视,破坏民族团结的;</span></p>
-      <p class="text-color"><span class="text-font">(7)破坏国家宗教政策,宣扬邪教和封建迷信的;</span></p>
-      <p class="text-color"><span class="text-font">(8)散布谣言,扰乱经济秩序和社会秩序,破坏社会稳定的;</span></p>
-      <p class="text-color"><span class="text-font">(9)散布淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪的;</span></p>
-      <p class="text-color"><span class="text-font">(10)侮辱或者诽谤他人,侵害他人名誉、隐私和其他合法权益的;</span></p>
-      <p class="text-color"><span class="text-font">(11)法律、行政法规禁止的其他内容。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">2、制作、上传、复制、传送、传播包含下列内容的不良信息:</span></h2>
-      <p class="text-color"><span class="text-font">(1)使用夸张标题,内容与标题严重不符的;</span></p>
-      <p class="text-color"><span class="text-font">(2)炒作绯闻、丑闻、劣迹等的;</span></p>
-      <p class="text-color"><span class="text-font">(3)不当评述自然灾害、重大事故等灾难的;</span></p>
-      <p class="text-color"><span class="text-font">(4)带有性暗示、性挑逗等易使人产生性联想的;</span></p>
-      <p class="text-color"><span class="text-font">(5)展现血腥、惊悚、残忍等致人身心不适的;</span></p>
-      <p class="text-color"><span class="text-font">(6)煽动人群歧视、地域歧视等的;</span></p>
-      <p class="text-color"><span class="text-font">(7)宣扬低俗、庸俗、媚俗内容的;</span></p>
-      <p class="text-color"><span class="text-font">(8)可能引发未成年人模仿不安全行为和违反社会公德行为、诱导未成年人不良嗜好等的;</span></p>
-      <p class="text-color"><span class="text-font">(9)其他对网络生态造成不良影响的内容。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">您知悉并同意,您不得向其他用户发布具有跟踪性、威胁性、伤害性、骚扰性或令人尴尬的内容;不得针对性、性别、年龄、体重、体形、残障、种族、宗教或性取向发表任何贬损性言论,亦不得支持针对任何个人或群体实施暴力行为,即使是以幽默的方式所表达,这包括针对任何群体或社区发表任何成见。在您参与线上沟通时,请围绕相关话题就事论事,您可以礼貌地对某条消息、帖子或某个话题表示反对,但请勿以嘲讽或侮辱的方式攻击其他用户。在您受到其他用户的攻击时,如果您反过来攻击对方,那么对方可能还会再次攻击您。</span></h2>
-      <p class="text-color"><span class="text-font">3、以任何方式危害未成年人,包括但不限于制作、上传、复制、传送、传播诱发未成年人模仿违反社会公德和违法犯罪行为的内容,含有恐怖、残酷等妨害未成年人身心健康的内容,含有披露未成年人个人隐私的内容。</span></p>
-      <p class="text-color"><span class="text-font">4、利用本服务从事危害网络安全的活动:</span></p>
-      <p class="text-color"><span class="text-font">(1)非法侵入门墩儿招聘或他人网络、干扰门墩儿招聘或他人网络正常功能、窃取网络数据等危害网络安全的活动。包括但不限于:出于任何目的,在未经授权的情况下使用、破坏或企图破坏、自动攻击、开发或滥用我们的资源或我们的网络安全保护措施,使用任何网络机器人、网络蜘蛛(SPIDER)、抓取工具、抓宠程序、拟人程序或其他非真实用户或避开、破坏技术措施等非正常的自动手段读取、复制、转存访问本服务的任何内容,未经门墩儿招聘许可使用插件、外挂或者通过其他第三方工具、运营平台或任何服务接入本服务和相关系统;对本服务的网络服务及相关软硬件设施进行破解、破坏、删除、修改或者增加,对计算机信息网络中存储或者传输的数据和应用程序进行删除、修改或者增加的;</span></p>
-      <p class="text-color"><span class="text-font">(2)上传、复制、传送、传播任何干扰、破坏或限制任何计算机软件、硬件或通讯设备功能的软件病毒或其他计算机代码、档案和程序之资料,干扰或破坏本服务或与提供本服务相连的服务器和网络;</span></p>
-      <p class="text-color"><span class="text-font">(3)向他人提供专门用于从事侵入网络、干扰网络正常功能及防护措施、窃取网络数据等危害网络安全活动的程序、工具。</span></p>
-      <p class="text-color"><span class="text-font">(4)明知他人从事危害网络安全的活动的,为其提供技术支持、广告推广、支付结算等帮助的行为。</span></p>
-      <p class="text-color"><span class="text-font">(5)其他违反法律法规,危害计算机网络安全的行为。</span></p>
-      <p class="text-color"><span class="text-font">5、以通过发布评论等任何方式向任何人发布任何垃圾信息。</span></p>
-      <p class="text-color"><span class="text-font">6、篡改其他用户发布的内容。</span></p>
-      <p class="text-color"><span class="text-font">7、任何未经授权的商业行为。包括但不限于:</span></p>
-      <p class="text-color"><span class="text-font">(1)对本服务的全部或任何部分,进行复制、拷贝、出售、转售或用于任何其他商业目的;</span></p>
-      <p class="text-color"><span class="text-font">(2)利用本服务进行任何牟利性经营活动等。</span></p>
-      <p class="text-color"><span class="text-font">(3)传播任何未经要求或授权的广告、宣传材料、“邮寄宣传片”、“垃圾邮件”、“连环信”、传销、违法直销或任何其他形式的此类兜售;</span></p>
-      <p class="text-color"><span class="text-font">(4)发布包含经我们自行判断后认为令人反感或者妨碍任何其他人士使用或享用本服务的内容;</span></p>
-      <p class="text-color"><span class="text-font">(5)发布可能会使我们或其他用户受到任何类型的任何伤害或承担任何责任的内容;</span></p>
-      <p class="text-color"><span class="text-font">(6)发布损害或降低与我们的标志有关的商誉的内容,包括但不限于:</span></p>
-      <p class="text-color"><span class="text-font">(7)强制、诱导其他用户关注、点击链接页面或分享信息;</span></p>
-      <p class="text-color"><span class="text-font">(8)未经门墩儿招聘书面许可利用门墩儿招聘账号和任何功能进行推广或互相推广的;</span></p>
-      <p class="text-color"><span class="text-font">(9)利用技术手段批量建立虚假账号。</span></p>
-      <p class="text-color"><span class="text-font">8、将无权传送的内容(例如受保密协议保护的保密资料、机密资料)、侵犯他人的个人信息、著作权、专利权、商标权、商业秘密或其他专属权利之内容、广告函件、促销资料、干扰、破坏或限制任何计算机软件、硬件或通讯设备功能的软件病毒或其他计算机代码、档案和程序之资料等作为任何内容进行上传、复制、传送、传播;</span></p>
-      <p class="text-color"><span class="text-font">9、从事侵害他人名誉权、肖像权、知识产权、商业秘密、隐私、个人信息等合法权益的行为。包括但不限于:</span></p>
-      <p class="text-color"><span class="text-font">(1)以任何不当手段侵扰他人;</span></p>
-      <p class="text-color"><span class="text-font">(2)违法收集、发布个人信息,发布与任何第三方有关或者违法向任何第三方收集包含个人信息的内容,包括用户通过在线课堂可能披露的个人信息,例如的电话号码、街道地址、姓名等;</span></p>
-      <p class="text-color"><span class="text-font">(3)未经本人的明确许可,公布其个人信息,包括但不限于手机号码、住址、姓名等;</span></p>
-      <p class="text-color"><span class="text-font">(4)公开发布私人对话,包括公开自其他用户收到的私人消息。</span></p>
-      <p class="text-color"><span class="text-font">(5)以其他任何方式非法获取、使用、出售、提供其他用户的个人信息;</span></p>
-      <p class="text-color"><span class="text-font">(6)其他违反法律法规或国家政策以及损害我们及他人合法权益的行为。</span></p>
-      <p class="text-color"><span class="text-font">10、利用本服务服务从事违法犯罪活动。包括但不限于:</span></p>
-      <p class="text-color"><span class="text-font">(1)设立用于实施诈骗,传授犯罪方法,制作或者销售违禁物品、管制物品等违法犯罪活动的网站、通讯群组;</span></p>
-      <p class="text-color"><span class="text-font">(2)利用本服务发布涉及实施诈骗,制作或者销售违禁物品、管制物品以及其他违法犯罪活动的信息;</span></p>
-      <p class="text-color"><span class="text-font">(3)利用门墩儿招聘账号或本服务从事欺诈、传销、刷流量、好评等任何违法犯罪活动;</span></p>
-      <p class="text-color"><span class="text-font">(4)利用本服务从事洗钱、窃取商业秘密、窃取个人信息等违法犯罪活动。</span></p>
-      <p class="text-color"><span class="text-font">(5)在不符合中国有关法规的情况下,从中国大陆向境外传输资料信息。</span></p>
-      <p class="text-color"><span class="text-font">11、冒充任何人或机构。包括但不限于:</span></p>
-      <p class="text-color"><span class="text-font">(1)冒充门墩儿招聘工作人员或以虚伪不实的方式谎称或使人误认为门墩儿招聘与任何人或任何机构有关;</span></p>
-      <p class="text-color"><span class="text-font">(2)伪造标题或以其他方式使人误认为该内容为门墩儿招聘发布、传送;</span></p>
-      <p class="text-color"><span class="text-font">(3)仿冒、混淆他人账号昵称、头像或发布内容,或冒充、利用他人名义;</span></p>
-      <p class="text-color"><span class="text-font">(4)盗用他人头像或资料,冒充、利用他人名义。</span></p>
-      <p class="text-color"><span class="text-font">12、未能按照本服务的流程、规则进行注册、认证或使用本服务的,违反本服务功能限制或运营策略,或采取任何措施规避本服务的流程、规则、限制或策略的。</span></p>
-      <p class="text-color"><span class="text-font">13、使用本服务在本服务上制作、上传、发布、传播任何违反法律法规及其他规范性文件、本规范及《门墩儿招聘用户服务协议》的文字、图片等内容的。</span></p>
-      <p class="text-color"><span class="text-font">14、不遵守本协议之约定或教唆他人从事本协议所禁止的行为。</span></p>
-      <p class="text-color"><span class="text-font">15、违反任何相关的法律、法规、规章、条例等其他具有法律效力的规范。</span></p>
-      <p class="text-color"><span class="text-font">16、其他任何导致或可能导致我们与第三方产生纠纷、争议或诉讼的行为。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">四、违约责任</span></h2>
-      <h2 class="subtitle text-size"><span class="text-font">为了维护平台的良好秩序及用户权益,如果您出现违反有关法律法规以及本协议的情况,包括但不限于发布违法信息或本协议及本协议的关联协议中明令禁止发布的内容,以及恶意损害本网站声誉、商誉或违反有关法律法规、本协议以及相关网站、App 、小程序使用规则的行为,我们有权自行判断并视情节严重程度,决定采取以下一种或多种处置措施:警示、拒绝发布、删除信息、屏蔽或断开连接、限制功能、限期改正、限制账号功能、按照平台要求出具不再发生违规行为的保证及其他证明文件并根据实际情况决定是否恢复服务、暂停更新直至关闭账号、中止/终止向您提供部分/全部服务、封禁/回收用户账号、禁止重新注册、不予退还已支付费用、要求您赔偿门墩儿招聘因此遭受的全部损失(包括但不限于财产损害赔偿、名誉损害赔偿、律师费、交通费等因维权而产生的合理费用,定义下同)等处理措施。</span></h2>
-      <h2 class="subtitle text-size"><span class="text-font">此外,您的行为如涉及违法犯罪活动的,门墩儿招聘有权单方终止提供全部或部分智联产品与/或服务,并移交司法机关进行处理。如因上述处理措施给用户带来任何损失或者因此无法使用门墩儿招聘账号和服务的,门墩儿招聘对此不承担任何责任。</span></h2>
-      <h2 class="subtitle text-size"><span class="text-font">由此导致的一切不利后果,由用户自行承担;导致第三方损害的,用户应当独立承担责任;因用户的上述行为给我们造成不利后果的,用户应负责消除影响,并且赔偿我们因此遭受的一切损失,包括但不限于财产损害赔偿、名誉损害赔偿、律师费、交通费等因维权而产生的合理费用。</span></h2>
-      <p class="text-color"><span class="text-font">用户上传的内容非用户原创的,用户保证对该内容已经取得了合法授权(包含转授权),有权以《门墩儿招聘用户服务协议》及本规范约定的方式授权给门墩儿招聘使用,若用户违反上述保证,导致的任何争议或纠纷由用户自行解决;
-        <strong>由此给门墩儿招聘造成损失的,用户应当对门墩儿招聘承担赔偿责任,包括但不限于财产损害赔偿、名誉权损害赔偿、律师费、交通费等因维权而产生的合理费用。</strong></span></p>
-      <p class="text-color"><span class="text-font">如用户因违反《门墩儿招聘用户服务协议》或本规范导致第三方损害的,用户应当独立承担责任,门墩儿招聘不因此承担任何责任;如有任何第三方向我们主张权益,您应当为我们积极向第三方抗辩,或者按照我们的要求,为我们向第三方抗辩提供必要的配合与协助(包括但不限于提供与相关权利证明文件、资料、信息等);
-        <strong>造成门墩儿招聘损失的,用户应当对门墩儿招聘承担赔偿责任,包括但不限于财产损害赔偿、名誉权损害赔偿、律师费、交通费等因维权而产生的合理费用。</strong></span></p>
-      <h2 class="subtitle text-size"><span class="text-font">五、附则</span></h2>
-      <p class="text-color"><span class="text-font">1.本行为规范的订立、执行和解释及争议的解决均应适用中国法律并受中国法院管辖。如您与门墩儿招聘就本规范内容或其执行发生任何争议,双方应友好协商解决;协商不成时,任何一方均可向苏州工业园区人民法院提起诉讼。</span></p>
-      <p class="text-color"><span class="text-font">2.本规范自发布之日起施行,门墩儿招聘有权基于法律规定的变化、平台功能的调整,以及自身管理经验的不断丰富等,出于维护门墩儿招聘平台秩序的目的,不断修订并完善本规范。用户应经常查阅并了解本规范,以便获得最新信息。</span></p>
-    </div>
-  </div>
-</template>
-
-<style scoped lang="scss">
-@import '../../static/style/protocol/index.scss';
-</style>

+ 0 - 27
pagesB/agreement/WorkplaceCommunityPolicy.vue

@@ -1,27 +0,0 @@
-<template>
-  <div class="conter">
-    <div class="Protocol">
-      <h1 class="segment">职场社区政策</h1>
-      <p class="text-color"><span class="text-font">我们将竭诚为会员提供专业的“服务”,为更好提供服务,我们制定此职场社区政策。职场社区政策旨在规范何种行为在社区是被允许的,何种行为在社区是被禁止的。您在使用本网站服务时,应该遵守此规定。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">1. 个人资料</span></h2>
-      <p class="text-color"><span class="text-font">本网站要求会员必须提供真实的姓名和准确的个人资料。您在使用本网站服务时不得以使用他人姓名、图像或其他个人信息来假冒他人,也不得以任何其他形式使他人误解您隶属于某个企业或组织。同时不得使用不属于您本人的账户,不得创建除本网站用户协议规定以外的非真实用户。在上传档案头像时,必须是您本人的图像。同时,您不得操控识别码以伪装通过服务传递任何消息或动态来源。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">2. 发布内容</span></h2>
-      <p class="text-color"><span class="text-font">您在本网站交流及所发布之内容务必与本网站宗旨相一致,不得做出不当行为。您在本网站使用服务时所创建之内容,必须遵守本网站相关政策规定,并且所创建之内容应该与本网站服务内容相关。不得邀请您所无法识别其真实身份的人加入您的人脉,不要将错误的或未经证实信息在本网站进行分享。你所发布的内容不得明示或暗示含有任何色情内容。您也不得发布任何含有暴力或妨害风化等内容,同时不得在使用本网站服务时从事任何违法犯罪活动。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">3. 社区氛围</span></h2>
-      <p class="text-color"><span class="text-font">本网站所倡导之交流应该是积极、向上、充满正能量氛围。不得在本网站发表攻击他人或企业的不当言论。此类言论包含但不限于辱骂或羞辱性言语、讽刺及影射性言论、未经允许发布他人未经公开的个人资料、或者煽动他人进行此类行为。</span></p>
-      <p class="text-color"><span class="text-font">您不得利用本网站之服务发表鼓吹暴力、组织犯罪、煽动仇恨、散布偏见言论等行为。您不得利用本网站之服务为恐怖组织进行招募,或者利用本网站为恐怖组织进行宣传或报道恐怖活动等。</span></p>
-      <p class="text-color"><span class="text-font">您不得在使用本网站服务时发布暴力或露骨内容,或意图恫吓或羞辱他人。不允许鼓吹、组织、描绘或助长犯罪活动;不允许叙述或鼓吹指导武器制作、药物滥用和盗窃威胁等相关内容;也不允许宣传或鼓励自杀或任何自我伤害的举动,包括自残、绝食或暴食等内容或活动。</span></p>
-      <p class="text-color"><span class="text-font">您不得在使用本网站服务时发送无特定对象、无相关性、不想要、未经请求、未经授权、不恰当的商业或促销,或无故重复的消息。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">4. 合法使用</span></h2>
-      <p class="text-color"><span class="text-font">您在使用本网站服务时所分享和使用的作品、商标、私人信息或商业秘密等必须首先保证您具有合法的权限。本网站所提供的服务不应被用于非法活动、宣传非法产品或侵犯他人权利。请勿使用本网站进行诈骗或企图蒙骗他人的活动。</span></p>
-      <p class="text-color"><span class="text-font">您在使用本网站的服务时您不得在未经授权的情况下向不认识的本网站会员征求邮箱地址或其他个人资料;不得使用、揭露或散布任何以违反本网站政策或协议之方式取得的资料;不得发布您未获同意即公开的信息。</span></p>
-      <p class="text-color"><span class="text-font">您在使用本网站服务时必须遵守相关法律、法规,包括但不限于知识产权法、税法及监管要求。您不得使用本网站服务从事传销活动、参与欺诈等违法犯罪活动。</span></p>
-      <p class="text-color"><span class="text-font">您在使用本网站服务时不得违反他人的知识产权,包括版权、专利、商标、商业机密或其他所有权。</span></p>
-      <p class="text-color"><span class="text-font">您在使用本网站服务时不得侵害本网站权利。您必须遵守我们的规则、协议和政策。</span></p>
-    </div>
-  </div>
-</template>
-
-<style scoped lang="scss">
-@import '../../static/style/protocol/index.scss';
-</style>

+ 0 - 44
pagesB/agreement/index.vue

@@ -1,44 +0,0 @@
-<template>
-  <view class="pb-120">
-    <view class="card">
-      <uni-list>
-        <uni-list-item
-          v-for="item in list"
-          :clickable="true"
-          :key="item.title"
-          :title="item.title"
-          showArrow
-          :rightText="item.rightTex || ''"
-          @click="handleToLink(item)"
-        >
-        </uni-list-item>
-      </uni-list>
-    </view>
-  </view>
-</template>
-
-<script setup>
-const list = [
-	{	title: '用户协议',	path: '/pagesB/agreement/user' },					
-	{	title: '隐私协议',	path: '/pagesB/agreement/privacy' },					
-	{	title: '版权政策',	path: '/pagesB/agreement/CopyrightPolicy' },					
-	{	title: '职场社区政策',	path: '/pagesB/agreement/WorkplaceCommunityPolicy' },					
-	{	title: '用户行为规范',	path: '/pagesB/agreement/UserBehaviorNorms' },					
-]
-
-const handleToLink = (item) => {
-	uni.navigateTo({
-		url: item.path
-	})
-}
-</script>
-<style scoped lang="scss">
-:deep(.uni-list-item) {
-	height: 120rpx !important;
-	line-height: 120rpx !important;
-}
-:deep(.uni-list-item__content-title) {
-	font-size: 32rpx !important;
-	font-weight: 500;
-}
-</style>

+ 0 - 51
pagesB/agreement/privacy.vue

@@ -1,51 +0,0 @@
-<template>
-  <view class="conter">
-    <view class="Protocol">
-      <h1 class="segment">隐私政策</h1>
-      <h2 class="subtitle text-size"><span class="text-font">引言</span></h2>
-      <p class="text-color"><span class="text-font">苏州识喜识谊信息科技有限公司(“识喜识谊”、“我们”、“我们的”)尊重您的隐私,致力于保护您在使用我们的网站www.menduner.com、企业公众服务号、小程序、其他线上产品和服务(“网站”)、在您注册网站会员时、或在您以其他方式与我们互动时,提供给我们、或我们收集的属于您的个人信息的隐私性、保密性和安全性。</span></p>
-      <p class="text-color"><span class="text-font">本网站关注每一位用户的权益,珍视您的隐私,此隐私保障政策解释了我们的个人信息实际操作和您能够选择的个人信息被使用的方式。此隐私保障政策是我们对您个人信息保护的承诺,并已被所有识喜识谊其关联公司或子公司所采纳。</span></p>
-      <p class="text-color"><span class="text-font">在下列情形下,您将被要求同意此隐私保障政策中的各项条款:注册会员、享受会员服务、注册加入活动或促销活动、通过网站与我们联系或适用法律法规所要求的其他情况。除此之外,您对本网站的继续使用将视为您已同意该隐私保障政策的各项条款。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">数据使用</span></h2>
-      <p class="text-color"><span class="text-font">我们给您提供的服务将基于您提供的数据。</span></p>
-      <p class="text-color"><span class="text-font">在您确定使用我们的服务,以及您使用服务的方式及设置后,我们将确定如何使用您的个人数据。为更好为您提供服务,我们在使用您的个人数据进行服务时,将借助智能系统进行处理。</span></p>
-      <p class="text-color"><span class="text-font">为更好提供服务,我们将对服务内容进行更新,由此造成的数据采集内容及使用方式的变更,我们将及时通知您,同时可能会对本政策进行修改。</span></p>
-      <p class="text-color"><span class="text-font">我们在使用您的个人信息时将以合理、合法为原则。我们将在以下几个方面使用您的个人信息。</span></p>
-      <p class="text-color"><span class="text-font">1. 我们收集的个人信息将被用于确保我们产品和服务的功能和安全、验证您的身份、防止并追究欺诈或其他不当使用的情形。</span></p>
-      <p class="text-color"><span class="text-font">2. 我们收集的个人信息将被用于我们的产品和服务开发,尽管一般情况下,我们为此目的仅使用综合信息和统计性信息。</span></p>
-      <p class="text-color"><span class="text-font">3. 我们收集的个人信息将被用于与您进行交流,例如在本网站产品或服务更新、发布的第一时间向您发出通知。</span></p>
-      <p class="text-color"><span class="text-font">4. 我们所收集的个人信息将被用于进行产品的个性化设计,并向您提供更优化的服务。</span></p>
-      <p class="text-color"><span class="text-font">5. 为了更好的为您提供服务,本网站可能将您同意公开的姓名、简历信息、个人标签、职位等信息推送给适合的招聘或求职用户。</span></p>
-      <p class="text-color"><span class="text-font">6. 如果您参与本网站举办的调查、抽奖、竞赛或类似推广活动,我们会将您提供的个人信息用于管理此类活动。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">信息分享</span></h2>
-      <p class="text-color"><span class="text-font">1. 与本公司其他产品或关联公司产品或共享:为更好的向您提供服务,推荐您可能感兴趣的信息,您的部分个人信息可能会共享给本公司其他产品或者关联公司的产品。我们只会共享必要的个人信息,例如共享您的行为偏好,以向您推荐同类信息。</span></p>
-      <p class="text-color"><span class="text-font">2. 为更好提供服务,我们可能会在《用户协议》框架内及法律允许的范围内将您的信息与第三方信息进行匹配,从而为您量身定制相关信息。在使用过程中,我们会采取一切必要措施保证您的个人数据安全。随着我们业务的持续发展,我们以及我们的关联公司有可能进行合并、收购、资产转让或类似的交易,我们收集的相关信息有可能作为此类交易的一部分而被转移。</span></p>
-      <p class="text-color"><span class="text-font">3. 法律声明</span></p>
-      <p class="text-color"><span class="text-font">如果我们或我们的关联公司依照法律、法规、法院命令、监管机构命令的要求,或根据政府的行为、监管要求或请求,或为了保护您、我们和他人的权利与安全,我们也许需要共享您的数据。</span></p>
-      <p class="text-color"><span class="text-font">我们将根据法律及相关政策要求,在以下情况下公开您的信息: (1) 相关政府执法部门在执法过程中需要进行协助的;(2) 根据《用户协议》可以公开的;(3) 针对任何第三方主张或指控进行调查与自我辩护;(4) 保护我们“服务”的安全性或完整性;或 (5) 行使或保护本网站、“会员”、职员或他人的权利和安全。在应法律及相关政策要求需要提供您个人数据时,我们将根据情况尽力通知您。</span></p>
-      <p class="text-color"><span class="text-font">4. 管理变更或出售</span></p>
-      <p class="text-color"><span class="text-font">将来我们可能会被出售、合并等管理主体变更时,您的数据依然会被新的管理主体共享,但本政策会被继续遵守。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">您的选择与义务</span></h2>
-      <p class="text-color"><span class="text-font">1. 数据保留</span></p>
-      <p class="text-color"><span class="text-font">在您使用我们账号的过程中,您的数据将被我们保留。此数据包含您提供的数据及我们经过推断而产生的数据等。</span></p>
-      <p class="text-color"><span class="text-font">2. 访问与控制个人数据的权利</span></p>
-      <p class="text-color"><span class="text-font">对于您的个人数据,您可以随时查看和更改,同时我们对于您数据的收集、使用、共享提供了多种选择。</span></p>
-      <p class="text-color"><span class="text-font">数据管理:</span></p>
-      <p class="text-color"><span class="text-font">删除数据:您可以要求我们清除或删除您的全部或部分个人数据。</span></p>
-      <p class="text-color"><span class="text-font">更改或纠正数据: 您可以通过您的帐号编辑您的部分个人数据。</span></p>
-      <p class="text-color"><span class="text-font">限制对数据的使用:您可以要求我们停止使用您的全部或部分个人数据。</span></p>
-      <p class="text-color"><span class="text-font">3. 注销帐号</span></p>
-      <p class="text-color"><span class="text-font">在您被注销帐号之后,我们仍然会保留您的部分数据。</span></p>
-      <p class="text-color"><span class="text-font">在您注销您的本网站帐号后24小时内,您的个人数据将不再向其他人显示。以下情形除外:</span></p>
-      <p class="text-color"><span class="text-font">法律或相关政策要求、遵守监管要求、解决争议、保证安全、防止欺诈与滥用、执行《用户协议》或满足您向我们“退订”某些消息的请求,即使您注销帐号,本网站仍可能保留您的部分个人数据。在您的帐号注销后,我们将保留不可识别个人的信息。</span></p>
-      <p class="text-color"><span class="text-font">您已与他人分享的信息在您注销帐号或从职业档案或收件箱中删除后,将仍对他人公开,并且我们无法控制其他“会员”从我们的“服务”中复制的信息。与注销帐号相关的群组内容、评分或点评内容,会以“未知用户”列为内容来源。您的职业档案可能继续显示在其他方的服务中,直到其更新缓存。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">联系信息</span></h2>
-      <p class="text-color"><span class="text-font">您可以联系我们或使用其他方式来解决任何投诉。</span></p>
-      <p class="text-color"><span class="text-font">若您对本《隐私政策》有任何疑问或投诉,您可以通过邮件来联系我们。</span></p>
-    </view>
-  </view>
-</template>
-
-<style scoped lang="scss">
-@import '../../static/style/protocol/index.scss';
-</style>

+ 0 - 78
pagesB/agreement/user.vue

@@ -1,78 +0,0 @@
-<template>
-  <view class="conter">
-    <view class="Protocol">
-      <h1 class="segment">用户协议</h1>
-      <h2 class="subtitle text-size"><span class="text-font">1.引言</span></h2>
-      <p class="text-color"><span class="text-font">1.1苏州识喜识谊信息科技有限公司同意按照本协议的规定及其不时发布的操作规则提供门墩儿网站,小程序(www.menduner.com)(以下称“本网站”或“我们”)网络服务,为获得网络服务,服务使用人(以下称“用户”或“您”,包括酒店管理者及相关从业人员、企业用户等)应当同意本协议的全部条款并按照页面上的提示完成全部的注册程序。用户在进行注册程序过程中勾选“我已阅读并同意”选项表示您完全接受并遵守本用户协议项下的全部条款,请您务必仔细阅读,充分理解协议的条款内容后再点击同意确认,您点击同意后即视为已接受本用户协议为构成对双方具有约束力的法律文件。</span></p>
-      <p class="text-color"><span class="text-font">1.2用户注册完成后,用户账号和密码由用户自行保管,用户应当对以其账号进行的所有活动和事件负法律责任。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">2.用户使用限制及收费</span></h2>
-      <p class="text-color"><span class="text-font">2.1本网站的会员只适用于已年满十八周岁,且具备相应的民事行为能力签订本用户协议。十六周岁至十八周岁的未成年人如希望使用服务,请由未成年人的监护人注册账号和填写相关信息。本网站不对任何不具备完全民事行为能力的主体开放,完全民事行为能力以外的人不是本网站的合格使用者,本网站有权采取包括但不限于注销账户的处理措施,并向使用者的监护人或负责人索偿。</span></p>
-      <p class="text-color"><span class="text-font">2.2本网站有权限制您使用“服务”时与会员建立联系和进行互动的方式。</span></p>
-      <p class="text-color"><span class="text-font">2.3本网站保留限制您使用“服务”的权利,包括限制您联系人的数量和您与其他会员互动的能力。如果本网站认为您可能违反了本合同或法律,或对“服务”使用不当 (如违反任何应做或禁止事项或职场社区政策),本网站将保留限制、暂停或终止您帐号的权利。因本网站主要接纳的会员为酒店管理者及相关从业人员、企业用户等,如果本网站认为您不属于上述会员范畴,本网站将保留限制、暂停或终止您帐号的权利。</span></p>
-      <p class="text-color"><span class="text-font">2.4本网站对部分“服务”收取一定的费用。在此情况下,本网站会在相关页面上做明确的提示。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">3.用户授权</span></h2>
-      <p class="text-color"><span class="text-font">用户应确保提供给本网站的所有内容、反馈和个人信息均具有真实性、准确性、完整性以及合法有效性,同时用户也授予门墩儿网站享有如下权限:在不需要另行通知并取得用户授权的情况下免费在全球范围内,可以使用、复制、修改、传播、发表、加工用户通过本网站“服务”提供的信息和内容,以上权限可以转让及可以授权给第三方。</span></p>
-      <p class="text-color"><span class="text-font">本网站在使用这些权限时有如下限制:</span></p>
-      <p class="text-color"><span class="text-font">3.1您可以通过删除“服务”里的特定内容或注销帐号,来终止您授予本网站的权限,但该内容已经被您或他人分享时已经被他人复制、重新分享或保存了该内容的除外;</span></p>
-      <p class="text-color"><span class="text-font">3.2您的内容将不会被我们用于商业目的。但本网站免费享有在您的内容旁发布广告的权利;</span></p>
-      <p class="text-color"><span class="text-font">3.3如果我们想给予第三方在“服务”范围之外发布您发表内容的权利,须取得您的同意。但是,如果您选择“公开,我们将允许会员将您的公开动态嵌入第三方服务,还将允许搜索引擎通过其服务将这些公开内容作为可被查找的内容。</span></p>
-      <p class="text-color"><span class="text-font">3.4 您的内容可能会被我们在不更改本身含义的情况下进行编辑或修改。</span></p>
-      <p class="text-color"><span class="text-font">3.5 我们将根据您所提供的信息及数据,向您推送相关的信息及服务。</span></p>
-      <p class="text-color"><span class="text-font">3.6在遵守《隐私政策》的条款以及您同意前提下,您和本网站同意,我们能访问、保存、处理和使用您提供的任何信息和个人数据。</span></p>
-      <p class="text-color"><span class="text-font">3.7您承诺您所提供的档案是真实的,同时您所发布的信息和内容没有任何侵权。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">4.用户使用规则</span></h2>
-      <p class="text-color"><span class="text-font">4.1用户义务</span></p>
-      <p class="text-color"><span class="text-font">4.1.1遵守中华人民共和国相关法律法规,包括但不限于《中华人民共和国数据安全法》《中华人民共和国网络安全法》《个人信息保护法》等有关法律和法规;</span></p>
-      <p class="text-color"><span class="text-font">4.1.2提供准确信息,并及时更新信息;在职业档案中使用真实姓名。</span></p>
-      <p class="text-color"><span class="text-font">4.2用户禁止事项:</span></p>
-      <p class="text-color"><span class="text-font">4.2.1在本网站上创建虚假身份,并以此为本人或他人谋取不正当利益;</span></p>
-      <p class="text-color"><span class="text-font">4.2.2未经本网站同意进行“服务”数据采集或复制“服务”中的职业档案等其他信息;</span></p>
-      <p class="text-color"><span class="text-font">4.2.3未经本网站同意,复制、使用、公开或传播任何通过“服务”获得的信息,无论是直接获得还是通过第三方(例如搜索引擎)获得的;</span></p>
-      <p class="text-color"><span class="text-font">4.2.4侵犯其他任何第三方专利权、著作权、商标权、名誉权或其他任何合法权益;</span></p>
-      <p class="text-color"><span class="text-font">4.2.5侵犯本网站的知识产权或其他权利;</span></p>
-      <p class="text-color"><span class="text-font">4.2.6未经本网站明确同意,不得以本网站名义从事任何商业及收费商业活动;</span></p>
-      <p class="text-color"><span class="text-font">4.2.7未经本网站同意,以宣传您的本网站档案或某个本网站群组以外的任何目的,深层链接到“服务”;</span></p>
-      <p class="text-color"><span class="text-font">4.2.8 使用自动程序(即“bots”)或其他自动方法访问“服务”、添加或下载通讯录、发送或重定向信息;</span></p>
-      <p class="text-color"><span class="text-font">4.2.9以任何竞争目的监控“服务”的可用性、性能或功能;</span></p>
-      <p class="text-color"><span class="text-font">4.2.10 参与“建立构架”、“制作镜像”或其他模拟“服务”外观或功能的活动;</span></p>
-      <p class="text-color"><span class="text-font">4.2.11擅自修改本网站“服务”或其外观;</span></p>
-      <p class="text-color"><span class="text-font">4.2.12干扰“服务”的运营、或给“服务”带来不合理的负荷(例如群发邮件、拒绝服务攻击、病毒、游戏运算);和/或违反在您注册或开始使用某项特定“服务”时所规定的《职业社区政策》或任何附加条款。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">5.服务变更</span></h2>
-      <p class="text-color"><span class="text-font">本网站可能会修改、暂停或取消某些本网站所提供的服务,或会自行更改价格,本网站无法承诺保存或持续展示您发布的任何信息和内容。在法律允许的范围内,这些更改可能在向您发送通知时开始生效。本网站没有义务保存、维护您或他人提供的任何信息和内容,也没有义务提供这些内容和信息的副本。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">6. 知识产权</span></h2>
-      <p class="text-color"><span class="text-font">6.1本网站保留“服务”中的所有知识产权。使用“服务”并不代表您对我们的“服务”或通过“服务”提供的内容或信息拥有任何所有权。本网站在本服务中提供的内容(包括但不限于网页、文字、图片、音频、视频、图表等)的知识产权均归本网站所有,但本服务中涉及广告的知识产权由相应广告商享有的,用户在使用本服务前对自己发布的内容已合法取得知识产权的、在内容中声明了转载或经过第三方授权,且非通过载入第三方网页的除外。</span></p>
-      <p class="text-color"><span class="text-font">6.2除另有特别声明外,本网站提供服务时所依托软件的著作权、专利权及其他知识产权均归门墩儿网站所有。</span></p>
-      <p class="text-color"><span class="text-font">6.3与“服务”相关的商标和标志是其各自所有者的商标。本网站以及本网站服务使用的其他本网站商标、服务标志、图片和标志均为本网站的商标或注册商标。未经本网站事先书面同意,用户不得将本网站的标识以任何方式展示或使用或用作其他处理,也不得向他人表明用户有权展示、使用、或其他有权处理本网站标识的行为。</span></p>
-      <p class="text-color"><span class="text-font">6.4 基于对数据的合法加工而获得的具有竞争性的数据权益,除法律法规另有规定外,我们享有独立的使用权益而无须获得您的同意。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">7.风险提示</span></h2>
-      <p class="text-color"><span class="text-font">7.1由于本网站一般不对会员及他人提供的内容进行审查,如果您在使用服务时看到不准确、不完整、过时、有误导性、非法、冒犯性或有害的内容或信息,本网站不对以上信息负责。</span></p>
-      <p class="text-color"><span class="text-font">7.2如果您通过本网站“服务”上的链接访问或使用第三方 APP 、小程序或网站进行访问,通过以上方式进行访问时,他们可能会获取并使用您的相关信息,本网站对上述风险不承担责任。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">8.免责声明和有限责任</span></h2>
-      <p class="text-color"><span class="text-font">8.1本网站对由于政府禁令、现行生效的适用法律或法规的变更、火灾、地震、动乱、战争、停电、通讯线路中断、黑客攻击、计算机病毒侵入或发作、电信部门技术调整、因政府管制而造成网站的暂时性关闭等任何影响网络正常运营的不可预见、不可避免、不可克服和不可控制的事件(“不可抗力事件”),以及他人蓄意破坏、本网站工作人员的疏忽或不当使用,正常的系统维护、系统升级,或者因网络拥塞而导致本网站不能访问而造成的本网站所提供的信息及数据的延误、停滞或错误,以及使用者由此受到的一切损失不承担任何责任;</span></p>
-      <p class="text-color"><span class="text-font">8.2本网站不对用户的线下行为负责。企业用户及个人用户均应审慎对待他方之行为,因为他方之行为给用户造成任何不利影响的,本网站不承担任何法律责任。</span></p>
-      <p class="text-color"><span class="text-font">8.3本网站对于向用户免费提供的服务或向用户赠送的任何产品或者服务的质量缺陷及其引发的任何损失,本网站无需承担任何责任。</span></p>
-      <p class="text-color"><span class="text-font">8.4对于本网站为使用者提供便利而设置的外部链接网址,本网站并不保证其准确性、安全性和完整性,亦并不代表本网站对其链接内容的认可,请使用者谨慎确认后使用,本网站对由此导致的任何损失或伤害不承担任何责任。</span></p>
-      <p class="text-color"><span class="text-font">8.5用户因使用本网站产生损失而提出的索赔金额,以用户向本网站已交付的款项之和为限。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">9. 协议终止</span></h2>
-      <p class="text-color"><span class="text-font">9.1双方可于任何时候终止本协议。</span></p>
-      <p class="text-color"><span class="text-font">9.2本网站或您均可在任何时间通知对方终止本协议。一旦协议终止,您就失去了访问或使用“服务”的权利。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">10. 适用法律和纠纷解决</span></h2>
-      <p class="text-color"><span class="text-font">若您我双方发生法律纠纷,双方同意在苏州工业园区人民法院解决,适用中华人民共和国的法律。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">11.适用语言及其他</span></h2>
-      <p class="text-color"><span class="text-font">11.1在法律允许的范围内,本合同的中文版本将具法律效力,其他语言版本仅起参考作用。</span></p>
-      <p class="text-color"><span class="text-font">11.2您不得在没有取得本网站同意的情况下将本合同(包括您的会员身份或“服务”使用权)转让或转移给任何人。但是,您同意本网站可以在没有您同意的情况下将本合同转让给关联机构或本网站的收购方。本合同不存在第三方受益者。</span></p>
-      <p class="text-color"><span class="text-font">11.3用户理解并同意,本网站对于用户所有的通知均可以通过网页公告、电子邮件、手机短信、微信模板信息方式进行;该等通知于发送之日视为已送达收件人。</span></p>
-      <p class="text-color"><span class="text-font">11.4用户对于本网站的通知应当通过本网站对外正式公布的通信地址、电子邮件地址等联系信息进行送达。</span></p>
-      <h2 class="subtitle text-size"><span class="text-font">12. 联系信息</span></h2>
-      <p class="text-color"><span class="text-font">如果您想向我们发送通知或送达法律文件,请联系我们:</span></p>
-      <p class="text-color"><span class="text-font">地址:江苏省苏州工业园区林泉街 399 号东南大学国家 大学科技园(苏州)南工院(2#)304 室</span></p>
-      <p class="text-color"><span class="text-font">邮编:215123</span></p>
-      <p class="text-color"><span class="text-font">公司:苏州识喜识谊信息科技有限公司</span></p>
-      <p class="text-color"><span class="text-font">邮箱:services@menduner.com</span></p>
-    </view>
-  </view>
-</template>
-
-<style scoped lang="scss">
-@import '../../static/style/protocol/index.scss';
-</style>

+ 0 - 64
pagesB/contactUs/index.vue

@@ -1,64 +0,0 @@
-<template>
-  <view class="main">
-    <view class="main-footer">
-      <uni-title type="h3" title="欢迎关注,了解门墩儿的新动态。"></uni-title>
-      <view class="subTitle">门墩儿在所有主流社交媒体都有账号。欢迎关注我们,以便了解关于发展趋势和领导力问题的最新见解。</view>
-      <view class="main-footer-contact">
-        <view class="main-footer-contact-item"><text>猎头顾问</text>:潘青海 Peter Pan</view>
-        <view class="main-footer-contact-item"><text>邮箱</text>:peter.pan@menduner.com</view>
-        <view class="main-footer-contact-item"><text>手机</text>:18621329797</view>
-        <view class="qr">
-          <image
-            src="https://minio.menduner.com/dev/defc03d54c8673c708f03babe212c223834606495c7a1b00d837c9b462553400.jpg"
-            mode="scaleToFill"
-          />
-          <view class="subTitle">关注menduner公众号</view>
-        </view>
-      </view>
-    </view>
-  </view>
-</template>
-
-<script setup>
-</script>
-
-<style lang="scss" scoped>
-.main {
-  &-footer {
-    width: 100%;
-    padding: 30rpx;
-    box-sizing: border-box;
-    background: #f5f5f5;
-    .subTitle {
-      font-size: 24rpx;
-      margin-bottom: 20rpx;
-      line-height: 40rpx;
-      color: #666;
-    }
-    &-contact {
-      &-item {
-        margin-bottom: 20rpx;
-        text {
-          display: inline-block;
-          width: 140rpx;
-          text-align-last: justify;
-        }
-      }
-      
-    }
-    .qr {
-      image {
-        width: 240rpx;
-        height: 240rpx;
-        margin-bottom: 10rpx;
-      }
-      width: 100%;
-      display: flex;
-      justify-content: center;
-      flex-direction: column;
-      align-items: center;
-      margin-top: 20rpx;
-    }
-  }
-}
-</style>

+ 0 - 16
pagesB/jobFair/addJob.vue

@@ -1,16 +0,0 @@
-<template>
-  <view>
-    <position :fairId="jobFairId" />
-  </view>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import position from '@/components/positionItem'
-
-const jobFairId = ref('')
-onLoad((options) => {
-	jobFairId.value = options.jobFairId
-})
-</script>

+ 0 - 266
pagesB/jobFair/details.vue

@@ -1,266 +0,0 @@
-<template>
-	<view class="box" :style="`background-color: ${jobFairInfo?.backgroundColour}`">
-		<view class="d-flex" style="padding: 15px 15px 0 15px;">
-			<view class="title-line"></view>
-			<rich-text class="title" :nodes="jobFairInfo?.title?.replace(/<\/?p[^>]*>/gi, '')"></rich-text>
-		</view>
-
-		<uni-segmented-control :current="tab" :values="controlList" @clickItem="tabChange" styleType="text" activeColor="#00B760" />
-		<scroll-view class="scrollBox" :scroll-y="true" style="position:relative;" @scrolltolower="loadingMore">
-			<JobItem 
-				v-if="jobFairPosition?.length"
-				:list="jobFairPosition"
-				:jobFairId="id"
-				:tab="tab"
-				:jobFairName="jobFairInfo?.title?.replace(/<\/?p[^>]*>/gi, '')"
-				@refresh="tabChange({ currentIndex: tab })"
-			/>
-			<uni-load-more v-else status="noMore" />
-		</scroll-view>
-
-    <view class="addBtn" @tap="handleClickAdd">
-      <view class="addBox">
-        <view class="icon">+</view>
-        <view class="text">发布新职位</view>
-      </view>
-    </view>
-
-		<view class="bottom-sticky">
-			<view class="bottom-content">
-				<button class="btnStyle bgButtons ss-m-l-15" type="primary" plain="true" @tap.stop="handleToShare">分享海报</button>
-        <button class="buttons btnStyle" type="primary" @tap.stop="handleJoinJobFair">克隆职位发布</button>
-      </view>
-		</view>
-	</view>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import { onLoad, onShow } from '@dcloudio/uni-app'
-import { getJobFair, getJobFairPosition } from '@/api/jobFair.js'
-import { getJobAdvertisedList } from '@/api/new/position'
-import { dealDictArrayData } from '@/utils/position.js'
-import JobItem from './jobItem.vue'
-import { getAccessToken } from '@/utils/request'
-import { showAuthModal } from '@/hooks/useModal'
-
-const id = ref(null)
-const tab = ref(0)
-const controlList = ['招聘中', '已关闭']
-
-// 获取招聘会信息
-const jobFairInfo = ref({})
-const getJobFairInfo = async () => {
-  const { data } = await getJobFair(id.value)
-  if (!data) return
-  jobFairInfo.value = data || {}
-}
-
-// 招聘中职位
-const jobFairPosition = ref([])
-const getJobList = async () => {
-  try {
-		uni.showLoading({ title: '加载中' })
-		const { data } = await getJobFairPosition(id.value)
-		if (!data || !data.length) {
-			jobFairPosition.value = []
-			return
-		}
-		jobFairPosition.value = dealDictArrayData([], data)
-  } finally {
-    uni.hideLoading()
-  }
-}
-
-// 已关闭职位
-const more = ref('more')
-const pageTotal = ref(0)
-const pageInfo = ref({
-  pageSize: 10,
-  pageNo: 1
-})
-const getProgressJobList = async () => {
-  if (pageInfo.value.pageNo < 1) return
-  if (pageInfo.value.pageNo === 1) jobFairPosition.value = []
-  try {
-    more.value = 'loading'
-    const res = await getJobAdvertisedList({ ...pageInfo.value, status: '1', jobFairId: id.value, hire: false })
-    const list = res?.data?.list?.length ? res.data.list : []
-    pageTotal.value = res.data.total-0
-    if (!list?.length) {
-      more.value = 'noMore'
-      return
-    }
-    jobFairPosition.value.push(...dealDictArrayData([], list))
-    more.value = 'more'
-    if (jobFairPosition.value.length === pageTotal.value) {
-      more.value = 'noMore'
-      return
-    }
-  } catch (error) {
-    pageInfo.value.pageNo--
-    more.value = 'more'
-  }
-}
-
-// 加载更多
-const loadingMore = () => {
-	// 招聘中职位列表不需要加载更多,属于一次性拿回全部
-	if (tab.value === 0) return
-  if (more.value === 'noMore') return
-
-  more.value = 'loading'
-  pageInfo.value.pageNo++
-  getProgressJobList()
-}
-
-const tabChange = (e) => {
-  tab.value = e.currentIndex
-  jobFairPosition.value = []
-  
-  if (tab.value === 0) return getJobList()
-  pageInfo.value.pageNo = 1
-  getProgressJobList()
-}
-
-// 职位新增
-const handleClickAdd = () => {
-  if (!getAccessToken()) {
-		uni.showToast({
-			title: '请先登录',
-			icon: 'none'
-		})
-		showAuthModal()
-		return
-	}
-  uni.navigateTo({ url: '/pagesB/jobFair/addJob?jobFairId=' + id.value })
-}
-
-onLoad((options) => {
-	id.value = options.id
-	if (!id.value) {
-		uni.showToast({
-			title: '缺少招聘会id',
-			icon: 'none'
-		})
-		setTimeout(() => {
-			uni.navigateBack({ delta: 1 })
-		}, 1000)
-		return
-	}
-
-	getJobFairInfo()
-	getJobList()
-})
-
-onShow(() => {
-	if (id.value) {
-    jobFairPosition.value = []
-    if (tab.value) {
-      pageInfo.value.pageNo = 1
-      getProgressJobList()
-      return
-    }
-    getJobList()
-  }
-})
-
-// 加入招聘会
-const handleJoinJobFair = () => {
-  uni.navigateTo({
-		url: '/pagesB/jobFair/join?jobFairId=' + id.value
-	})
-}
-
-// 我的分享海报
-const handleToShare = () => {
-	uni.navigateTo({
-		url: '/pagesB/jobFair/jobFairEntShare?jobFairId=' + id.value
-	})
-}
-</script>
-
-<style scoped lang="scss">
-.title {
-	font-size: 18px;
-	color: #fff;
-}
-.title-line {
-	width: 7px;
-	height: 18px;
-	background-color: #fff;
-	margin-right: 10px;
-	border-radius: 6px;
-	margin-top: 3px;
-}
-.bottom-content {
-  display: flex;
-  justify-content: space-evenly;
-  align-items: center;
-  width: 100%;
-  margin: 20rpx 0;
-  .btnStyle {
-    flex: 1;
-    margin-right: 20rpx;
-		border-radius: 50rpx;
-  }
-  .bgButtons {
-    border: 2rpx solid #00B760;
-    color: #00B760;
-  }
-  &-tool {
-    width: 160rpx;
-    display: flex;
-    justify-content: center;
-    flex-direction: column;
-    align-items: center;
-  }
-}
-.box {
-  height: 100vh;
-  overflow: hidden;
-  box-sizing: border-box;
-  display: flex;
-  flex-direction: column;
-}
-.scrollBox{
-  flex: 1;
-  height: 0 !important;
-  padding-bottom: 100rpx;
-  box-sizing: border-box;
-}
-.addBtn{
-  position: fixed;
-  margin-bottom: 20px;
-  right: 35rpx;
-  bottom: calc(env(safe-area-inset-bottom) + 60px);
-  width: 70px;
-  .addBox {
-    position: relative;
-    .icon {
-      font-size: 42px;
-      color: #fff;
-      background-color: #00B760;
-      width: 50px;
-      height: 50px;
-      line-height: 46px;
-      text-align: center;
-      border-radius: 50%;
-      margin: 0 auto;
-      box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3);
-    }
-    .text {
-      position: absolute;
-      top: 42px;
-      font-size: 12px;
-      color: #00B760;
-      background-color: #ffffffc9;
-      text-align: center;
-      padding: 2px 4px;
-      margin: 0 auto;
-      border-radius: 6px;
-      // box-shadow: 0 36px 6px rgba(0, 0, 0, 0.1);
-    }
-  }
-}
-</style>

+ 0 - 21
pagesB/jobFair/editJob.vue

@@ -1,21 +0,0 @@
-<template>
-  <view>
-    <position :jobId="jobId" :fairId="jobFairId" :isClone="isClone" />
-  </view>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import position from '@/components/positionItem'
-
-const jobId = ref('')
-const jobFairId = ref('')
-const isClone = ref(false)
-
-onLoad((options) => {
-	jobFairId.value = options.jobFairId
-  jobId.value = options.jobId
-  if (options?.isClone) isClone.value = true
-})
-</script>

+ 0 - 237
pagesB/jobFair/jobFairEntShare.vue

@@ -1,237 +0,0 @@
-<template>
-  <view style="position: relative;">
-    <view v-if="shareUrl" class="d-flex align-center flex-column justify-center" style="height: 100vh;">
-      <image v-if="!!shareUrl" :style="imgStyle" @click="handlePreviewSharePoster" :src="shareUrl" :show-menu-by-longpress="true"></image>
-      <view class="color-999 ss-m-t-20 font-size-14 ss-m-b-50">点击图片预览,长按图片保存</view>
-    </view>
-		<canvas canvas-id="posterCanvas" class="shareCanvas" style="width: 540px; height: 788px;"></canvas>
-  </view>
-</template>
-
-<script setup>
-import { ref, computed } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import { getJobAdvertisedShareQrcode } from '@/api/user'
-import { getJobFairPosition, getJobFair, saveShareQuery } from '@/api/jobFair'
-import { formatName } from '@/utils/getText'
-import { userStore } from '@/store/user'
-
-const useUserStore = userStore()
-const shareUrl = ref('')
-const windowWidth = ref(0)
-let jobFairId = '' // 分享会ID
-let entLogoUrl = useUserStore?.userInfo?.logoUrl || 'https://minio.menduner.com/dev/cd7f5e26a239fb0ab335585e04c709b065f52832fc31539b3a5423224fc6d16c.png'
-let entName = formatName(useUserStore?.userInfo?.enterpriseAnotherName || useUserStore?.userInfo?.enterpriseName) || '门墩儿' // 企业名称
-let shareImg = '' // 分享背景图片-底图
-
-onLoad(async (options) => {
-  jobFairId = options.jobFairId
-  await getJobFairDetail()
-  await getEntPositionList()
-  const windowInfo = wx.getWindowInfo()
-  windowWidth.value = windowInfo.windowWidth
-  if (shareImg) createPoster() // 生成海报
-})
-
-const getJobFairDetail = async () => {
-  if (!jobFairId) return
-  const { data } = await getJobFair(jobFairId)
-  shareImg = data?.contentImg || ''
-}
-
-let positionNameList = []
-const getEntPositionList = async () => {
-  if (!jobFairId) {
-    uni.showToast({ title: '获取企业岗位失败,请重试!', icon: 'none', duration: 2000 })
-    return
-  }
-  try {
-    const { data } = await getJobFairPosition(jobFairId)
-    positionNameList = data.map(e => { return formatName(e?.name) }).slice(0, 3)
-  } catch (error) {}
-}
-
-const imgStyle = computed(() => {
-  if (windowWidth.value <= 320) return `width: 259px; height: 377px;`
-  if (windowWidth.value > 320 && windowWidth.value <= 375) return `width: 313px; height: 455px;`
-  if (windowWidth.value > 375) return `width: 328px; height: 474px;`
-})
-
-// 图片预览
-const handlePreviewSharePoster = () => {
-	uni.previewImage({
-		current: 0,
-		longPressActions: {
-			itemList: ['发送给朋友', '保存图片', '收藏']
-		},
-		urls: [shareUrl.value]
-	})
-}
-
-const getImageTempRatio = (url) => {
-  return new Promise((req, rej)=>{
-    wx.getImageInfo({
-      src:url,
-      success:(res) =>{
-        req(res)
-      }
-    })
-  })
-}
-
-const getToLocal = (base64data) => {
-  const fsm = wx.getFileSystemManager()
-  const FILE_BASE_NAME = `tmp_${new Date().getTime()}` // 自定义文件名
-  const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || []
-  if (!format) {
-    return (new Error('ERROR_BASE64SRC_PARSE'))
-  }
-  const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`
-  const buffer = wx.base64ToArrayBuffer(bodyData);
-  fsm.writeFile({
-    filePath,
-    data: buffer,
-    encoding: 'binary',
-    success(r) {
-      console.log(filePath,'filePath')
-      qrCode.value = filePath
-    },
-    fail() {
-      return (new Error('ERROR_BASE64SRC_WRITE'))
-    }
-  })
-}
-
-// 生成分享二维码
-const qrCode = ref()
-const handleShareCode = async () => {
-  const result = await saveShareQuery({ jobFairId, entName, enterpriseId: useUserStore?.userInfo?.enterpriseId })
-	const query = {
-		scene: 'id=' + result.data,
-    path: 'pagesB/jobFair/positionClassification',
-		width: 200,
-		autoColor: false,
-		checkPath: true,
-		hyaline: false // 二维码背景颜色为透明
-	}
-	const res = await getJobAdvertisedShareQrcode(query, { noAuth: true })
-	const data = res?.data ? 'data:image/png;base64,' + res.data : ''
-  getToLocal(data)
-}
-
-
-const createPoster = async () => {
-  uni.showLoading({ title: '生成中...', mask: true })
-  await handleShareCode() // 生产分享二维码
-  var context = uni.createCanvasContext('posterCanvas')
-
-  //清空画布
-  context.clearRect(0, 0, 540, 788)
-
-  //背景图片 
-  const { path: bgUrl } = await getImageTempRatio(shareImg)
-  context.drawImage(bgUrl, 0, 0, 540, 788) // 路径、x、y、宽、高
-
-  // 企业头像
-  context.save()
-  const secondImgWidth = 120
-  const secondImgHeight = 120
-  const x = (540 - secondImgWidth) / 2
-  const y = 788 - secondImgHeight - 460
-  context.beginPath()
-  context.arc(x + secondImgWidth / 2, y + secondImgHeight / 2, secondImgWidth / 2, 0, Math.PI * 2, true)
-  context.clip()
-  const { path: entLogoUrlPath } = await getImageTempRatio(entLogoUrl)
-  context.drawImage(entLogoUrlPath, x, y, secondImgWidth, secondImgHeight)
-  context.restore()
-  
-  // 企业名称
-  const maxTextWidth = 400
-  const fontStyle = 'bold 24px Arial'
-  context.font = fontStyle
-  let truncatedText = entName
-  while (context.measureText(truncatedText + '...').width > maxTextWidth && truncatedText.length > 0) {
-    truncatedText = truncatedText.slice(0, -1)
-  }
-  if (truncatedText !== entName) truncatedText += '...'
-  const textX = x + (secondImgWidth - context.measureText(truncatedText).width) / 2
-  const textY = y + secondImgHeight + 30
-  context.fillStyle = '#000'
-  context.fillText(truncatedText, textX, textY)
-  
-  // 职位标签
-  const tagPaddingLeftRight = 20
-  const tagPaddingTopBottom = 10
-  const tagRadius = 8
-  const tagSpacing = 22
-  let tagY = textY + tagSpacing + 10
-  positionNameList.forEach((tag) => {
-    let truncatedTag = tag
-    context.font = '18px Arial' // 绘制前设置字体,否则tagWidth受前面的font fontStyle影响
-
-    while (context.measureText(truncatedTag + '...').width > maxTextWidth - 2 * tagPaddingLeftRight && truncatedTag.length > 0) {
-      truncatedTag = truncatedTag.slice(0, -1)
-    }
-    if (truncatedTag !== tag) truncatedTag += '...'
-
-    const tagWidth = context.measureText(truncatedTag).width + 2 * tagPaddingLeftRight
-    const tagX = x + (secondImgWidth - tagWidth) / 2
-
-    context.fillStyle = '#00B760'
-    context.beginPath()
-    context.moveTo(tagX + tagRadius, tagY)
-    context.lineTo(tagX + tagWidth - tagRadius, tagY)
-    context.quadraticCurveTo(tagX + tagWidth, tagY, tagX + tagWidth, tagY + tagRadius)
-    context.lineTo(tagX + tagWidth, tagY + tagPaddingTopBottom * 2)
-    context.quadraticCurveTo(tagX + tagWidth, tagY + tagPaddingTopBottom * 2 + tagRadius, tagX + tagWidth - tagRadius, tagY + tagPaddingTopBottom * 2 + tagRadius)
-    context.lineTo(tagX + tagRadius, tagY + tagPaddingTopBottom * 2 + tagRadius)
-    context.quadraticCurveTo(tagX, tagY + tagPaddingTopBottom * 2 + tagRadius, tagX, tagY + tagPaddingTopBottom * 2)
-    context.lineTo(tagX, tagY + tagRadius);
-    context.quadraticCurveTo(tagX, tagY, tagX + tagRadius, tagY)
-    context.closePath()
-    context.fill()
-
-    context.fillStyle = '#fff'
-    context.fillText(truncatedTag, tagX + tagPaddingLeftRight, tagY + tagPaddingTopBottom + 10)
-
-    tagY += tagPaddingTopBottom * 2 + tagSpacing
-  })
-
-  
-  //分享二维码
-  context.drawImage(qrCode.value, 80, 550, 110, 110)
-
-  context.font = 'bold 18px Arial'
-  context.fillStyle = '#000'
-  context.fillText('海量职位火热招聘中', 280, 605)
-
-  context.font = '15px Arial'
-  context.fillStyle = '#999'
-  context.fillText('长按图片识别二维码', 290, 625)
-  
-
-  context.draw(false, () =>{
-    wx.canvasToTempFilePath({ 
-      canvasId: 'posterCanvas',
-      success:(res)=>{
-        shareUrl.value = res.tempFilePath
-        console.log('canvas-success', shareUrl.value)
-		    uni.hideLoading({})
-      },
-      fail:(err)=>{
-        uni.hideLoading({})
-        console.log('canvas-fail', err)
-      }
-    })
-  })
-}
-</script>
-
-<style scoped lang="scss">
-.shareCanvas {
-	position: fixed;
-	top: -99999upx;
-	left: -99999upx;
-	z-index: -99999;
-}
-</style>

+ 0 - 203
pagesB/jobFair/jobItem.vue

@@ -1,203 +0,0 @@
-<template>
-  <view>
-    <view v-if="list?.length" class="ss-p-b-30 ss-p-t-20 ss-p-x-30">
-			<view v-for="(item, index) in list" :key="index" class="mList">
-				<view v-if="item?.hrName" class="d-flex align-center item-top">
-          <view class="avatarBox">
-            <image class="enterAvatar" :src="getUserAvatar(item.hrHeadImg)"></image>
-          </view>
-          <view class="ss-m-l-20 label-text">{{ item?.hrName }}</view>
-        </view>
-        <view class="list-shape" :style="{'border-radius': item?.hrName ? '0 0 12px 12px' : '12px'}">
-          <view @tap.stop="handleToDetail(item)">
-						<view class="titleBox">
-							<view style="display: flex;align-items: center;">
-								<image src="/static/svg/jobFair.svg" class=" ss-m-r-10" style="width: 20px; height: 20px;"></image>
-								<rich-text v-if="item.name?.indexOf('style') !== -1" class="job-name" :nodes="item.name"></rich-text>
-								<view v-else class="job-name">{{ formatName(item.name) }}</view>
-							</view>
-						</view>
-						<view class="d-flex align-center justify-space-between ss-m-t-20">
-							<view class="font-size-13 ellipsis" style="flex: 1;">
-								<span class="tag-gap" style="color: #808080;">
-									<span>{{item.area?.str ?? '全国' }}</span>
-									<span class="divider-mx" v-if="item.eduName">|</span>
-									<span>{{item.eduName }}</span>
-									<span class="divider-mx" v-if="item.expName">|</span>
-									<span>{{item.expName }}</span>
-									<span class="divider-mx">|</span>
-									<span>{{!item.payFrom && !item.payTo ? '面议' : `${item.payFrom}-${item.payTo}${item.payName ? '/' + item.payName : ''}` }}</span>
-								</span>
-							</view>
-						</view>
-					</view>
-          <view class="sub-li-bottom ss-m-t-20">
-						<view class="sub-li-bottom-item color-primary" @tap.stop="handleToResume(item)">{{ item.count || 0 }} 已投递简历</view>
-						<view v-if="tab === 0" class="sub-li-bottom-item color-error" @tap.stop="handleAction(0, item.id)">关闭</view>
-						<view v-else class="sub-li-bottom-item color-primary" @tap.stop="handleAction(1, item.id)">激活</view>
-          </view>
-        </view>
-			</view>
-		</view>
-
-		<uni-popup ref="popup" type="dialog">
-			<uni-popup-dialog 
-				type="warn" 
-				cancelText="取消" 
-				confirmText="确定" 
-				title="系统提示" 
-				:content="`是否确认${actionType === 0 ? '关闭' : '激活'}此职位?`" 
-				@confirm="handleActionConfirm"
-				@close="handleActionClose"
-			></uni-popup-dialog>
-		</uni-popup>
-  </view>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import { formatName } from '@/utils/getText'
-import { getUserAvatar } from '@/utils/avatar'
-import { closeJobAdvertised, enableJobAdvertised } from '@/api/new/position'
-
-const emit = defineEmits(['refresh'])
-const props = defineProps({
-	list: Array,
-	jobFairId: [String, Number],
-	jobFairName: String,
-	tab: Number
-})
-
-// 查看职位详情
-const handleToDetail = (val) => {
-	uni.navigateTo({
-		url: `/pagesB/positionDetail/index?jobId=${val.id}&jobFairId=${props.jobFairId}&isEdit=${val.edit}`
-	})
-}
-
-
-// 查看职位投递简历
-const handleToResume = (val) => {
-	uni.navigateTo({
-		url: `/pagesA/resume/index?jobId=${val.id}&jobName=${formatName(val.name)}&jobFairId=${props.jobFairId}&jobFairName=${props.jobFairName}`
-	})
-}
-
-// 职位激活、关闭
-const popup = ref()
-const actionId = ref('')
-const actionType = ref('')
-const handleAction = (type, id) => {
-	actionId.value = id
-	actionType.value = type
-	popup.value.open()
-}
-const handleActionClose = () => {
-	actionId.value = ''
-	actionType.value = ''
-	popup.value.close()
-}
-const handleActionConfirm = async () => {
-	if (!actionId.value || !props.jobFairId) {
-		uni.showToast({ title: '正在维护中,请稍后再试', icon: 'none', duration: 2000 })
-		return
-	}
-	uni.showLoading({ title: '加载中' })
-	const api = actionType.value === 0 ? closeJobAdvertised : enableJobAdvertised
-	try {
-		await api(actionId.value)
-		uni.showToast({ title: '操作成功', icon: 'none' })
-		emit('refresh')
-	} finally {
-		uni.hideLoading()
-		actionId.value = ''
-		actionType.value = ''
-	}
-}
-</script>
-
-<style scoped lang="scss">
-.enterAvatar{
-	width: 60rpx;
-	height: 60rpx;
-	margin: auto;
-	border-radius: 50%;
-}
-.avatarBox {
-  max-width: 60rpx;
-  max-height: 60rpx;
-}
-.item-top {
-  padding: 20rpx 30rpx;
-  background: linear-gradient(90deg,#f5fcfc,#fcfbfa);
-  border-radius: 12px 12px 0 0;
-  font-size: 28rpx;
-  color: #0E100F;
-  .label-text {
-	  max-width: 100%;
-	  text-overflow: ellipsis;
-	  white-space: nowrap;
-	  overflow: hidden;
-  }
-}
-.job-name {
-  font-size: 16px;
-  font-weight: 700;
-  color: #0E100F;
-  max-width: 80vw;
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-}
-
-.sub-li-bottom {
-  display: flex;
-  justify-content: space-between;
-  margin-top: 10px;
-  font-size: 13px;
-  color: #666;
-	&-item {
-		width: 50%;
-		height: 35px;
-		line-height: 35px;
-		text-align: center;
-		margin-right: 15px;
-		background-color: #f7f8fa;
-		border-radius: 4px;
-		&:nth-child(2) {
-			margin-right: 0;
-		}
-	}
-}
-
-.salary-text {
-	float: right;
-	color: #00B760;
-  font-weight: 700;
-}
-.list-shape {
-  background-color: #fff;
-	padding: 30rpx;
-  .titleBox {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-  }
-}
-.tag-gap{
-	margin: 10rpx 10rpx 10rpx 0;
-}
-.divider-mx{
-	margin: 0 10rpx;
-}
-.divider {
-	color:#e4d4d2;
-}
-.mList {
-  margin-bottom: 20rpx;
-	position: relative;
-  box-shadow: 1px 2px 12px rgba(0, 0, 0, 0.17);
-	background-color: #fbfbfb;
-	border-radius: 12px;
-}
-</style>

+ 0 - 236
pagesB/jobFair/join.vue

@@ -1,236 +0,0 @@
-<template>
-	<view class="box defaultBgc">
-		<view style="background-color: #fff;">
-			<uni-search-bar
-        v-model="query.name"
-        radius="5"
-        placeholder="输入关键字"
-        cancelButton="none"
-        :focus="false"
-				@clear="handleSearch"
-        @confirm="handleSearch"
-      ></uni-search-bar>
-		</view>
-		
-		<scroll-view class="scrollBox" :scroll-y="true" @scrolltolower="loadingMore" style="position:relative;">
-			<view  v-for="(item, index) in items" :key="index" class="mList">
-				<view v-if="item?.hrName" class="d-flex align-center item-top">
-          <view class="avatarBox">
-            <image class="enterAvatar" :src="getUserAvatar(item.hrHeadImg)"></image>
-          </view>
-          <view class="ss-m-l-20 label-text">{{ item?.hrName }}</view>
-        </view>
-        <view class="list-shape" :style="{'border-radius': item?.hrName ? '0 0 12px 12px' : '12px'}">
-          <view>
-						<view class="titleBox">
-							<view style="display: flex; align-items: center;">
-								<image v-if="item.jobFairId" src="/static/svg/jobFair.svg" class=" ss-m-r-10" style="width: 20px; height: 20px;"></image>
-								<rich-text v-if="item.name?.indexOf('style') !== -1" class="job-name" :nodes="item.name"></rich-text>
-								<view v-else class="job-name">{{ formatName(item.name) }}</view>
-								<span v-if="item.status === '1'" class="color-error">(已关闭)</span>
-							</view>
-						</view>
-						<view class="d-flex align-center justify-space-between ss-m-t-20">
-							<view class="font-size-13 ellipsis" style="flex: 1;">
-								<span class="tag-gap" style="color: #808080;">
-									<span>{{item.area?.str ?? '全国' }}</span>
-									<span class="divider-mx" v-if="item.eduName">|</span>
-									<span>{{item.eduName }}</span>
-									<span class="divider-mx" v-if="item.expName">|</span>
-									<span>{{item.expName }}</span>
-									<span class="divider-mx">|</span>
-									<span>{{!item.payFrom && !item.payTo ? '面议' : `${item.payFrom}-${item.payTo}${item.payName ? '/' + item.payName : ''}` }}</span>
-								</span>
-							</view>
-						</view>
-						<view v-if="item.jobFairName" class="color-primary font-size-13 ss-m-t-10">
-							招聘会:{{ item.jobFairName }}
-						</view>
-					</view>
-          <view class="sub-li-bottom">
-						<view class="sub-li-bottom-item" @tap.stop="handleJoin(item)">克隆加入</view>
-          </view>
-        </view>
-      </view>
-			<uni-load-more :status="more" />
-		</scroll-view>
-	</view>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import { formatName } from '@/utils/getText.js'
-import { getJobAdvertisedList } from '@/api/new/position'
-import { dealDictArrayData } from '@/utils/position'
-import { getUserAvatar } from '@/utils/avatar'
-
-const query = ref({
-	pageSize: 10,
-	pageNo: 1,
-	name: null
-})
-const items = ref([])
-const more = ref('more')
-const total = ref(0)
-
-const getData = async () => {
-  try {
-		more.value = 'loading'
-		const { data } = await getJobAdvertisedList(query.value)
-
-		if (!data.list.length) {
-			more.value = 'noMore'
-			items.value = []
-			total.value = 0
-			return
-		}
-
-		const list = dealDictArrayData([], data.list)
-		items.value = items.value.concat(list)
-		total.value = data.total
-
-		if (items.value.length === +data.total) {
-      more.value = 'noMore'
-      return
-    }
-	} catch {
-		query.value.pageNo--
-		more.value = 'more'
-	}
-}
-
-// 关键字搜索
-const handleSearch = () => {
-	total.value = 0
-	items.value = []
-	query.value.pageNo = 1
-	getData()
-}
-
-// 加载更多
-const loadingMore = () => {
-	if (more.value === 'noMore') return
-
-  more.value = 'loading'
-  query.value.pageNo++
-	getData()
-}
-
-const jobFairId = ref(null)
-onLoad(async (options) => {
-	if (options && options?.jobFairId) jobFairId.value = options.jobFairId
-
-	query.value.pageNo = 1
-	await getData()
-})
-
-// 克隆职位-跳转职位编辑
-const handleJoin = async (item) => {
-	if (!item.id) return uni.showToast({ title: '缺少职位ID', icon: 'none' })
-
-	const url = jobFairId.value ? 
-	`/pagesB/jobFair/editJob?jobId=${item.id}&jobFairId=${jobFairId.value}&isClone=1`
-	: `/pagesB/positionEdit/index?jobId=${item.id}&isClone=1`
-	uni.navigateTo({ url })
-}
-</script>
-
-<style scoped lang="scss">
-.enterAvatar{
-	width: 60rpx;
-	height: 60rpx;
-	margin: auto;
-	border-radius: 50%;
-}
-.avatarBox {
-  max-width: 60rpx;
-  max-height: 60rpx;
-}
-.item-top {
-  padding: 20rpx 30rpx;
-  background: linear-gradient(90deg,#f5fcfc,#fcfbfa);
-  border-radius: 12px 12px 0 0;
-  font-size: 28rpx;
-  color: #0E100F;
-  .label-text {
-	  max-width: 100%;
-	  text-overflow: ellipsis;
-	  white-space: nowrap;
-	  overflow: hidden;
-  }
-}
-.box {
-  height: 100vh;
-  overflow: hidden;
-  box-sizing: border-box;
-  display: flex;
-  flex-direction: column;
-}
-.scrollBox{
-	flex: 1;
-  padding-bottom: 24rpx;
-  box-sizing: border-box;
-	height: 0 !important;
-}
-.stickFilter {
-  z-index: 1;
-  position: sticky;
-  box-shadow: 0px 10rpx 12rpx 0px rgba(195, 195, 195, .25);
-  top: 110rpx;
-	background-color: #fff;
-}
-.job-name {
-  font-size: 16px;
-  font-weight: 700;
-  color: #0E100F;
-  max-width: 80vw;
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-}
-
-.sub-li-bottom {
-  display: flex;
-  justify-content: space-between;
-  margin-top: 10px;
-  padding-top: 10px;
-  font-size: 13px;
-  color: #00B760;
-	&-item {
-		width: 100%;
-		height: 35px;
-		line-height: 35px;
-		text-align: center;
-		background-color: #f7f8fa;
-		border-radius: 4px;
-	}
-}
-
-.list-shape {
-  background-color: #fff;
-	padding: 30rpx;
-  .titleBox {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-  }
-}
-.tag-gap{
-	margin: 10rpx 10rpx 10rpx 0;
-}
-.divider-mx{
-	margin: 0 10rpx;
-}
-.divider {
-	color:#e4d4d2;
-}
-.mList {
-	border-radius: 12px;
-	margin: 0 30rpx 20rpx 30rpx;
-  box-shadow: 1px 2px 12px rgba(0, 0, 0, 0.17);
-	&:first-child {
-		margin-top: 20rpx;
-	}
-}
-</style>

+ 0 - 30
pagesB/personnelDetails/components/advantage.vue

@@ -1,30 +0,0 @@
-<template>
-	<rich-text v-if="data" class="htmlCss" :nodes="cleanedHtml(data)"></rich-text>
-</template>
-
-<script setup>
-defineProps({ data: String })
-
-const cleanedHtml = (text) => {
-  const cleaned = text.replace(/\n/g, '<br>')
-  .replace(/\s+/g, ' ')
-  .replace(/(^|\s+)<\/p>(\s*<p>|$)/g, '</p><p>')
-  .replace(/<p>\s*(<br>)\s*<\/p>/g, '')
-  .replace(/<pre([^>]*)>/g, '<div$1>')
-  .replace(/<\/pre>/g, '</div>')
-  .replace(/<p>\s*(<\/br>)\s*<\/p>/g, '').trim()
-  return cleaned
-}
-</script>
-
-<style scoped lang="scss">
-.htmlCss {
-  white-space: pre-wrap;
-  word-break: break-all;
-  line-height: 28px;
-  color: var(--color-333);
-  font-size: 15px;
-  text-align: justify;
-  letter-spacing: 0;
-}
-</style>

+ 0 - 70
pagesB/personnelDetails/components/baseInfo.vue

@@ -1,70 +0,0 @@
-<template>
-	<view>
-		<view class="d-flex">
-			<view class="user-avatar">
-				<image class="user-avatar-img" :src="getUserAvatar(data?.avatar, data?.sex)" alt="" mode="scaleToFill" />
-				<image class="user-avatar-sex" :src="data?.sex ? data?.sex === '1' ? '/static/img/man.png' : '/static/img/female.png' : ''" alt="" mode="scaleToFill" />
-			</view>
-			<view class="user-left">
-				<view class="user-name">{{ data?.name }}</view>
-				<view class="ss-m-t-10">
-					<span 
-						class="color-666"
-					 	v-for="(key, index) in desc" 
-					 	:key="index"
-					>
-						{{ data[key] }}
-						<span v-if="index !== desc.length - 1 && data[key]" class="ss-m-x-10">|</span>
-					</span>
-				</view>
-			</view>
-		</view>
-		<view class="ss-m-t-10">
-      <uni-tag 
-        v-for="(tag,i) in data?.tagList || []"
-        :key="i"
-        class="tag-gap ss-m-r-10"
-        :text="tag"
-        inverted="false"
-        size="medium"
-        custom-style="background-color: #ececec; color: #666; border-color: #ececec; display: inline-block;margin-bottom: 10px;"
-      />
-    </view>
-	</view>
-</template>
-
-<script setup>
-defineProps({ data: Object })
-import { getUserAvatar } from '@/utils/avatar'
-
-const desc = ['jobStatusName', 'eduName', 'expName']
-</script>
-
-<style scoped lang="scss">
-.user-avatar {
-	position: relative;
-	&-img {
-		width: 65px;
-		height: 65px;
-		border-radius: 50%;
-	}
-	&-sex {
-		position: absolute;
-		right: 0;
-		bottom: 0;
-		width: 20px;
-		height: 20px;
-		background-color: #fff;
-		border-radius: 50%;
-	}
-}
-.user-left {
-	flex: 1;
-	margin-left: 10px;
-	.user-name {
-		font-size: 25px;
-		font-weight: 600;
-		color: #0E100F;
-	}
-}
-</style>

+ 0 - 58
pagesB/personnelDetails/components/eduExp.vue

@@ -1,58 +0,0 @@
-<template>
-	<view class="content">
-    <view
-      v-for="val in data"
-      :key="val.id"
-      class="content-item"
-    >
-      <view class="content-title">
-        <view class="name">{{ val.schoolName }}</view>
-        <view class="time">
-          {{ timesTampChange(val.startTime ,'Y-M') }} - {{ timesTampChange(val.endTime ,'Y-M') }}
-        </view>
-      </view>
-      <view class="content-subTitle">{{ val.major }} {{ dictObj.edu.find(e => e.value === val.educationType)?.label}}</view>
-    </view>
-  </view>
-</template>
-
-<script setup>
-defineProps({ data: Array })
-import { timesTampChange } from '@/utils/date'
-import { dictObj } from '@/utils/position'
-</script>
-
-<style scoped lang="scss">
-.content {
-  &-item {
-    padding: 20rpx 0;
-  }
-  &-title {
-    display: flex;
-    justify-content: space-between;
-    .name {
-      font-size: 30rpx;
-      color: #333;
-    }
-    .time {
-      color: #999;
-      font-size: 24rpx;
-      display: flex;
-      align-items: center;
-      .icon {
-        margin-left: 20rpx;
-      }
-    }
-  }
-  &-subTitle {
-    font-size: 24rpx;
-    margin-top: 6rpx;
-    color: #999;
-  }
-  &-main {
-    margin-top: 20rpx;
-    font-size: 24rpx;
-    color: #999;
-  }
-}
-</style>

+ 0 - 52
pagesB/personnelDetails/components/jobIntention.vue

@@ -1,52 +0,0 @@
-<template>
-	<view>
-		<view v-for="val in data" :key="val.id" class="ss-m-b-40">
-			<view class="item">
-        <view style="display: flex;justify-content: space-between;align-items: center;">
-          <text class="mr-20 item-title">{{ val.position}}</text>
-          <text class="color-error font-weight-bold">{{ val.payFrom }} {{ val.payFrom  && val.payTo ? '-' : ''}} {{ val.payTo}}</text>
-        </view>
-        <view>
-          {{ 
-            val.interestedArea && val.interestedArea.length 
-            ? 
-            (val.workArea ? val.workArea + ',' : '') + val.interestedArea.map(e => e.name).join(',') 
-            : 
-            (val.workArea || '')
-          }}
-        </view>
-        <view class="item-tags">
-          <view v-for="industry in val.industry" :key="industry.id" class="tag">{{ industry.nameCn }}</view>
-        </view>
-      </view>
-		</view>
-	</view>
-</template>
-
-<script setup>
-defineProps({ data: Array })
-</script>
-
-<style scoped lang="scss">
-.item {
-  font-size: 28rpx;
-  color: #666;
-  &-title {
-    color: #000;
-    font-weight: 600;
-  }
-  &-tags {
-    display: flex;
-    flex-direction: row;
-    flex-wrap: wrap;
-    .tag {
-      border: 2rpx solid #00B760;
-      color: #00B760;
-      padding: 4rpx 16rpx;
-      font-size: 24rpx;
-      margin: 10rpx 10rpx 0 0;
-      border-radius: 10rpx;
-    }
-  }
-}
-</style>

+ 0 - 72
pagesB/personnelDetails/components/trainingExperience.vue

@@ -1,72 +0,0 @@
-<template>
-	<view class="content">
-    <view
-      v-for="val in data"
-      :key="val.id"
-      class="content-item"
-    >
-      <view class="content-title">
-        <view class="name">{{ val.orgName }}</view>
-        <view class="time">
-          {{ timesTampChange(val.startTime ,'Y-M') }} - {{ val.endTime ? timesTampChange(val.endTime ,'Y-M') : '至今' }}
-        </view>
-      </view>
-      <view class="content-subTitle">课程:{{ val.course }}</view>
-      <view class="content-main ellipsis-2">
-				内容:
-				<rich-text v-if="val.content" :nodes="cleanedHtml(val.content)"></rich-text>
-			</view>
-    </view>
-  </view>
-</template>
-
-<script setup>
-defineProps({ data: Array })
-import { timesTampChange } from '@/utils/date'
-
-const cleanedHtml = (text) => {
-  const cleaned = text.replace(/\n/g, '<br>')
-  .replace(/\s+/g, ' ')
-  .replace(/(^|\s+)<\/p>(\s*<p>|$)/g, '</p><p>')
-  .replace(/<p>\s*(<br>)\s*<\/p>/g, '')
-  .replace(/<pre([^>]*)>/g, '<div$1>')
-  .replace(/<\/pre>/g, '</div>')
-  .replace(/<p>\s*(<\/br>)\s*<\/p>/g, '').trim()
-  return cleaned
-}
-</script>
-
-<style scoped lang="scss">
-.content {
-  &-item {
-    padding: 20rpx 0;
-  }
-  &-title {
-    display: flex;
-    justify-content: space-between;
-    .name {
-      font-size: 30rpx;
-      color: #333;
-    }
-    .time {
-      color: #999;
-      font-size: 24rpx;
-      display: flex;
-      align-items: center;
-      .icon {
-        margin-left: 20rpx;
-      }
-    }
-  }
-  &-subTitle {
-    font-size: 24rpx;
-    margin-top: 6rpx;
-    color: #999;
-  }
-  &-main {
-    margin-top: 20rpx;
-    font-size: 24rpx;
-    color: #999;
-  }
-}
-</style>

+ 0 - 72
pagesB/personnelDetails/components/workExp.vue

@@ -1,72 +0,0 @@
-<template>
-	<view class="content">
-    <view
-      v-for="work in data"
-      :key="work.id"
-      class="content-item"
-    >
-      <view class="content-title">
-        <view class="name">{{ work.enterpriseName }}</view>
-        <view class="time">
-          {{ timesTampChange(work.startTime ,'Y-M') }} - {{ work.endTime ? timesTampChange(work.endTime ,'Y-M') : '至今' }}
-        </view>
-      </view>
-      <view class="content-subTitle">{{ work.positionName }}</view>
-      <view class="content-main ellipsis-2">
-				内容:
-				<rich-text v-if="work.content" :nodes="cleanedHtml(work.content)"></rich-text>
-			</view>
-    </view>
-  </view>
-</template>
-
-<script setup>
-defineProps({ data: Array })
-import { timesTampChange } from '@/utils/date'
-
-const cleanedHtml = (text) => {
-  const cleaned = text.replace(/\n/g, '<br>')
-  .replace(/\s+/g, ' ')
-  .replace(/(^|\s+)<\/p>(\s*<p>|$)/g, '</p><p>')
-  .replace(/<p>\s*(<br>)\s*<\/p>/g, '')
-  .replace(/<pre([^>]*)>/g, '<div$1>')
-  .replace(/<\/pre>/g, '</div>')
-  .replace(/<p>\s*(<\/br>)\s*<\/p>/g, '').trim()
-  return cleaned
-}
-</script>
-
-<style scoped lang="scss">
-.content {
-  &-item {
-    padding: 20rpx 0;
-  }
-  &-title {
-    display: flex;
-    justify-content: space-between;
-    .name {
-      font-size: 30rpx;
-      color: #333;
-    }
-    .time {
-      color: #999;
-      font-size: 24rpx;
-      display: flex;
-      align-items: center;
-      .icon {
-        margin-left: 20rpx;
-      }
-    }
-  }
-  &-subTitle {
-    font-size: 24rpx;
-    margin-top: 6rpx;
-    color: #999;
-  }
-  &-main {
-    margin-top: 20rpx;
-    font-size: 24rpx;
-    color: #999;
-  }
-}
-</style>

+ 0 - 275
pagesB/personnelDetails/index.vue

@@ -1,275 +0,0 @@
-<template>
-	<view style="padding: 15px 15px 70px 15px;">
-		<baseInfo v-if="cvData?.person" :data="cvData?.person" />
-
-		<view v-if="skillExp?.length">
-			<view class="gap-line"></view>
-			<view class="title-line">职业技能</view>
-			<view class="tags">
-        <view
-          v-for="skill in skillExp"
-          :key="skill.title"
-          class="tag"
-        >
-          {{ skill.title }}
-        </view>
-      </view>
-		</view>
-
-		<view v-if="cvData?.person?.advantage">
-			<view class="gap-line"></view>
-			<view class="title-line">个人优势</view>
-			<advantage :data="cvData?.person?.advantage" />
-		</view>
-
-		<view v-if="cvData?.interestedList?.length">
-			<view class="gap-line"></view>
-			<view class="title-line">求职意向</view>
-			<jobIntention :data="dealJobData(cvData?.interestedList || [])" />
-		</view>
-
-		<view v-if="cvData?.eduList?.length">
-			<view class="gap-line"></view>
-			<view class="title-line">教育经历</view>
-			<eduExp :data="cvData?.eduList" />
-		</view>
-
-		<view v-if="cvData?.workList?.length">
-			<view class="gap-line"></view>
-			<view class="title-line">工作经历</view>
-			<workExp :data="cvData?.workList" />
-		</view>
-
-		<view v-if="cvData?.trainList?.length">
-			<view class="gap-line"></view>
-			<view class="title-line">培训经历</view>
-			<trainingExperience :data="cvData?.trainList" />
-		</view>
-
-		<view class="bottom-sticky">
-			<view class="bottom-content">
-        <!-- <button class="bottom-content-tool shareButtonCss" open-type="share">
-          <uni-icons type="redo-filled" size="24" color="#00B760" style="line-height: 24px;"/>
-          <span style="color:#00B760;font-weight:bold;line-height: 22px;">分享</span>
-        </button> -->
-				<button class="btnStyle bgButtons ss-m-l-15" type="primary" plain="true" @tap="handleSend">立即沟通</button>
-        <button class="buttons btnStyle" type="primary" @click="handleInvite">邀请面试</button>
-      </view>
-		</view>
-	</view>
-</template>
-
-<script setup>
-import { ref } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import { dealJobData } from '@/utils/dict'
-import { getDict } from '@/hooks/useDictionaries'
-import { getText } from '@/utils/getText'
-import { dealDictObjData } from '@/utils/position'
-import { getPersonCvDetail } from '@/api/enterprise.js'
-import baseInfo from './components/baseInfo.vue'
-import advantage from './components/advantage.vue'
-import jobIntention from './components/jobIntention.vue'
-import workExp from './components/workExp.vue'
-import eduExp from './components/eduExp.vue'
-import trainingExperience from './components/trainingExperience.vue'
-import { getJobAdvertisedList } from '@/api/new/position'
-import { defaultText, talkToUser } from '@/hooks/useIM'
-import { getAccessToken } from '@/utils/request'
-import { showAuthModal } from '@/hooks/useModal'
-
-const cvData = ref({})
-
-const skillExp = ref([])
-const getSkillExp = async (data) => {
-	if (!data || !data.length) {
-    return
-  }
-
-	const { data: _skillList} = await getDict('skillList', {}, 'skillList')
-  const skillList = _skillList?.data
-  if (!skillList || !skillList.length) {
-    return
-  }
-
-	const { data: _skillLevelArr } = await getDict('menduner_skill_level')
-  const skillLevelArr = _skillLevelArr?.data
-  if (!skillLevelArr || !skillLevelArr.length) {
-    return
-  }
-
-	skillExp.value = data.map(e => {
-    return {
-      ...e,
-      title: `${getText(e.skillId, skillList, 'nameCn', 'id')} / ${getText(e.level, skillLevelArr)}`
-    }
-  })
-}
-
-const getDetail = async (id) => {
-	uni.showLoading({ title: '加载中' })
-	try {
-		const { data } = await getPersonCvDetail(id)
-		if (!data) return
-		data.person = dealDictObjData({}, data.person)
-		cvData.value = data || {}
-		getSkillExp(data?.skillList || [])
-		uni.hideLoading()
-	} catch {
-		uni.hideLoading()
-	}
-}
-
-// 职位列表
-const jobNum = ref(0)
-const getJobList = async () => {
-  const { data } = await getJobAdvertisedList({ pageNo: 1, pageSize: 10, hasExpiredData: false, status: 0 })
-  jobNum.value = data?.total || 0
-}
-
-
-const btnType = ref('') // 1: 人才详情 2:简历投递
-onLoad(async (options) => {
-	const { id, type } = options
-	if (!id) {
-		uni.showToast({
-			title: '缺少人员id',
-			icon: 'none'
-		})
-		setTimeout(() => {
-			uni.navigateBack({ delta: 1 })
-		}, 1000)
-		return
-	}
-	btnType.value = type
-	await getDetail(id)
-
-	getJobList()
-})
-
-// 邀请面试
-const handleInvite = async () => {
-	if (!getAccessToken()) {
-    showAuthModal()
-    return
-  }
-  // 企业必须有招聘中的职位才能发起面试邀请
-  if (jobNum.value === 0) {
-		uni.showToast({
-			title: '请先发布招聘职位',
-			icon: 'none',
-			duration: 2000
-		})
-		return
-	}
-	uni.navigateTo({
-	  url: `/pagesB/InviteInterview/index?id=${cvData.value.person.userId}`
-	})
-}
-
-// 立即沟通
-const handleSend = async () => {
-	if (!getAccessToken()) {
-    showAuthModal()
-    return
-  }
-  // 企业必须有招聘中的职位才能发起沟通
-  if (jobNum.value === 0) {
-		uni.showToast({
-			title: '请先发布招聘职位',
-			icon: 'none',
-			duration: 2000
-		})
-		return
-	}
-  const userId = cvData.value.person.userId
-  if (!userId) return
-  const channel = await talkToUser({ userId, text: defaultText })
-
-	const query = {
-		id: userId,
-		name: cvData.value?.person?.name || cvData.value?.person?.phone,
-		channelID: channel.channelID,
-		channelType: channel.channelType,
-		avatar: cvData.value.person?.avatar,
-		sex: cvData.value.person?.sex,
-	}
-
-	const queryStr = Object.keys(query).reduce((r, v) => {
-		if (!query[v]) {
-			return r
-		}
-		return r += `${v}=${encodeURIComponent(query[v])}&`
-	}, '?')
-	uni.navigateTo({
-    url: `/pagesA/chart/index${queryStr.slice(0, -1)}`
-  })
-}
-</script>
-
-<style scoped lang="scss">
-.gap-line {
-	border-bottom: 1px solid #eee;
-	margin: 30px 0;
-}
-.title-line {
-	font-size: 20px;
-	position: relative;
-	line-height: 20px;
-	margin-left: 12px;
-	margin-bottom: 20px;
-	padding-left: 10px;
-	&::before {
-		content: '';
-		position: absolute;
-		width: 6px;
-		height: 20px;
-		background: #00B760;
-		left: -10px;
-		border-radius: 6px;
-	}
-}
-.tags {
-  display: flex;
-  flex-wrap: wrap;
-  .tag {
-    margin: 0 10rpx 10rpx 0;
-    border: 2rpx solid #00B760;
-    color: #00B760;
-    white-space: nowrap;
-    padding: 4rpx 10rpx;
-    border-radius: 10rpx;
-    font-size: 24rpx;
-  }
-}
-.bottom-content {
-  display: flex;
-  justify-content: space-evenly;
-  align-items: center;
-  width: 100%;
-  margin: 20rpx 0;
-  .btnStyle {
-    flex: 1;
-    margin-right: 20rpx;
-		border-radius: 50rpx;
-  }
-  .bgButtons {
-    border: 2rpx solid #00B760;
-    color: #00B760;
-  }
-  .shareButtonCss {
-    font-size: 16px;
-    background: unset;
-    &::after{
-      border:none !important;
-    }
-  }
-  &-tool {
-    width: 160rpx;
-    display: flex;
-    justify-content: center;
-    flex-direction: column;
-    align-items: center;
-  }
-}
-</style>

+ 0 - 9
pagesB/positionAdd/index.vue

@@ -1,9 +0,0 @@
-<template>
-  <view>
-    <position></position>
-  </view>
-</template>
-<script setup>
-import position from '@/components/positionItem'
-</script>
-<style scoped lang="scss"></style>

+ 0 - 40
pagesB/positionAdd/select.vue

@@ -1,40 +0,0 @@
-<template>
-  <view class="ss-p-50">
-    <uni-card class="ss-m-t-30" @tap="handleToAdd">
-      <view class="d-flex flex-column align-center ss-p-y-50">
-        <image src="https://minio.menduner.com/dev/119bd10c49a5059e84ee88c0ed601cb34709d81bff38ac8f23ada73069f6b8d3.png" class="svg ss-m-l-10"></image>
-        <view class="color-primary text-center MiSans-Medium" style="font-size: 24px">填写职位信息发布</view>
-      </view>
-    </uni-card>
-    <uni-card class="ss-m-t-80" @tap="handleToClone">
-      <view class="d-flex flex-column align-center ss-p-y-50">
-        <image src="https://minio.menduner.com/dev/cdb6e318f601c961c9307ea71ac24533af0e90acbcfad4ee3a7c0a6b093953a8.png" class="svg ss-m-l-10"></image>
-        <view class="color-primary text-center MiSans-Medium" style="font-size: 24px">克隆已有职位发布</view>
-      </view>
-    </uni-card>
-  </view>
-</template>
-
-<script setup>
-// 克隆职位发布
-const handleToClone = () => {
-	uni.navigateTo({
-		url: '/pagesB/jobFair/join'
-	})
-}
-
-// 填写职位信息发布
-const handleToAdd = () => {
-	uni.reLaunch({
-		url: '/pagesB/positionAdd/index'
-	})
-}
-</script>
-
-<style lang="scss" scoped>
-.svg {
-  width: 80px;
-  height: 80px;
-  margin-bottom: 30px;
-}
-</style>

+ 0 - 220
pagesB/positionDetail/index.vue

@@ -1,220 +0,0 @@
-<template>
-  <layout-page>
-    <scroll-view class="scrollBox" style="position:relative;">
-      <view class="box">
-        <view v-if="loading" class="vertical80-center">{{ loadingText }}</view>
-        <view v-else>
-          <view class="mt-5" style="display: flex;">
-            <!-- 赏金 -->
-            <view v-if="info.hire && info.hirePrice" class="hirePrice ss-m-r-10 d-flex align-center">
-              <view class="iconfont icon-a-1_zhaopin ss-m-r-10" style="color: #e03506; font-size: 20px;"></view>
-              <view>{{ `赏金:${commissionCalculation(info.hirePrice / 100, 1)}元` }}</view>
-            </view>
-            <image v-if="isJobFair" src="/static/svg/jobFair.svg" class="ss-m-r-10" style="width: 30px; height: 30px;"></image>
-            <!-- 职位名称 -->
-            <h2 class="JobName" style="flex: 1;">
-              {{ formatName(info.name) }}
-              <span v-if="info?.status === '1'" class="color-error">(职位已关闭)</span>
-            </h2>
-          </view>
-          <!-- 职位地区 -->
-          <view class="d-flex justify-space-between mt-5 align-center">
-            <view style="font-size: 14px; flex: 1; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; margin-right: 30px;">
-              <span>
-                <span>{{positionInfo?.area?.str ?? '全国' }}</span>
-                <span class="viewider-mx" v-if="positionInfo?.eduName">|</span>
-                <span>{{positionInfo?.eduName }}</span>
-                <span class="viewider-mx" v-if="positionInfo?.expName">|</span>
-                <span>{{positionInfo?.expName }}</span>
-              </span>
-            </view>
-          </view>
-          <view class="d-flex justify-space-between mt-5 align-center">
-            <!-- 薪资 -->
-            <view>
-              <span v-if="!info.payFrom && !info.payTo" class="salary w-600">面议</span>
-              <span v-else class="salary w-600">{{ info.payFrom }}-{{ info.payTo }}/{{ positionInfo.payName }}</span>
-            </view>
-          </view>
-          <view class="font-size-13 color-999 ss-m-t-10" style="text-align: end;">更新时间:{{ timesTampChange(info?.refreshTime || info.updateTime, 'Y-M-D h:m') }}</view>
-          <!-- 标签 -->
-          <view class="tagList mt">
-            <view class="tag" v-for="(tag,i) in info?.tagList || []" :key="'tagList' + i">
-              {{ tag }}
-            </view>
-          </view>
-          <!-- 岗位职责 -->
-          <view class="topLine fs14 mt-5">
-            <view class="fs15 w-600 my5">岗位职责</view>
-            <view v-if="!info.content"></view>
-            <rich-text v-else class="htmlCss" :nodes="cleanedHtml(info.content)"></rich-text>
-          </view>
-          <!-- 岗位要求 -->
-          <view class="topLine mt-5">
-            <view class="fs15 w-600 my5">岗位要求</view>
-            <view v-if="!info.requirement"></view>
-            <rich-text v-else class="htmlCss" :nodes="cleanedHtml(info.requirement)"></rich-text>
-          </view>
-          <!-- HR信息 -->
-          <view class="topLine mt-5 d-flex align-center">
-            <view class="avatarBox">
-              <image style="width: 40px; height: 40px; border-radius: 50%;" :src="getUserAvatar(info?.contact?.avatar)"></image>
-            </view>
-            <view class="contact-name">{{ info.contact?.name }}</view>
-          </view>
-          <!-- 工作地址 -->
-          <view class="topLine mt-5">
-            <view class="fs15 w-600 my5">工作地址</view>
-            <view class="my10">
-              <uni-icons
-                type="map-pin-ellipse"
-                color="#00B760"
-                class="mr"
-                size="25"
-              ></uni-icons>
-              <span style="color: var(--color-666);font-size: 15px;line-height: 26px;">{{ info.address || '' }}</span>
-            </view>
-          </view>
-        </view>
-      </view>
-    </scroll-view>
-    <view class="bottom-sticky" v-if="!loading && jobId">
-      <view class="bottom-content">
-        <button
-          v-if="info?.status === '0'"
-          class="buttons btnStyle ss-m-l-15"
-          type="primary"
-          @click="handleEdit"
-        >编辑职位</button>
-      </view>
-    </view>
-  </layout-page>
-</template>
-
-<script setup>
-import { commissionCalculation } from '@/utils/position'
-import { timesTampChange } from '@/utils/date'
-import layoutPage from '@/layout'
-import { ref, watch } from 'vue';
-import { getPositionDetails, getEnterprisePubJobTypePermission } from '@/api/position'
-import { dealDictObjData } from '@/utils/position'
-import { onLoad } from '@dcloudio/uni-app'
-import { userStore } from '@/store/user'
-import { formatName } from '@/utils/getText'
-import { getUserAvatar } from '@/utils/avatar'
-
-const useUserStore = userStore()
-const loading = ref(false)
-const loadingText = ref('加载中 . . . ')
-
-// 职位详情
-const info = ref({})
-const positionInfo = ref({})
-const beenLogin = ref(false)
-
-// 监听登录状态
-watch(() => useUserStore.refreshToken, (newVal) => {
-	beenLogin.value = Boolean(newVal)
-}, { immediate: true }, { deep: true })
-
-let jobId = ''
-const isJobFair = ref(false)
-let obj = {}
-const isEdit = ref(false)
-const fairNoEdit = ref(false)
-onLoad(async (options) => {
-  jobId = options?.id || options?.jobId || obj?.jobId || ''
-  
-  // 招聘会进入的岗位
-  if (options?.jobFairId) isJobFair.value = true
-  // 职位是否可编辑
-  if (options?.isEdit && options?.isEdit === 'true') isEdit.value = true
-  
-  // 发布中的招聘会是否可编辑
-  if (options?.fairNoEdit) fairNoEdit.value = true
-
-  if (jobId) {
-    loading.value = true
-    loadingText.value = '加载中 . . . '
-    getPositionDetail()
-  } else {
-    loadingText.value = '加载失败 . . . '
-  }
-})
-
-// 富文本内容处理,去除多余的换行空格等
-const cleanedHtml = (text) => {
-  const cleaned = text.replace(/\n/g, '<br>')
-  .replace(/\s+/g, ' ')
-  .replace(/(^|\s+)<\/p>(\s*<p>|$)/g, '</p><p>')
-  .replace(/<p>\s*(<br>)\s*<\/p>/g, '')
-  .replace(/<pre([^>]*)>/g, '<div$1>')
-  .replace(/<\/pre>/g, '</div>')
-  .replace(/<p>\s*(<\/br>)\s*<\/p>/g, '').trim()
-  return cleaned
-}
-
-// 职位详情
-async function getPositionDetail () {
-  try {
-    loading.value = true
-    const { data } = await getPositionDetails({ id: jobId })
-    info.value = data
-    positionInfo.value = { ...dealDictObjData({}, info.value), ...info.value, enterprise: dealDictObjData({}, data.enterprise) }
-    loading.value = false
-  } finally {
-  }
-}
-
-// 职位编辑
-const handleEdit = async () => {
-  if (!isJobFair.value && !isEdit.value) {
-    uni.showToast({ title: '职位发布时间超过24小时的不支持编辑', icon: 'none', duration: 2000 })
-    return
-  }
-  // 已关闭的招聘会职位不支持编辑
-  // if (isJobFair.value && info.value.status === '1') {
-  //   uni.showToast({ title: '职位已关闭', icon: 'none', duration: 2000 })
-  //   return
-  // }
-  // 发布中的招聘会职位需进入招聘会中进行编辑
-  if (fairNoEdit.value) {
-    uni.showToast({ title: '该职位属于招聘会职位,即将前往招聘会', icon: 'none', duration: 2000 })
-    setTimeout(() => {
-      uni.navigateTo({
-        url: `/pagesB/jobFair/details?id=${info.value.jobFairId}`
-      })
-    }, 1000)
-	  return
-  }
-  uni.showLoading({ title: '加载中 . . . ' })
-  try {
-    const res = await getEnterprisePubJobTypePermission()
-    if (!res?.data?.length) {
-      uni.showToast({ title: '没有该操作权限,请联系平台管理员升级后再试', icon: 'none', duration: 2000 })
-      return
-    }
-    const url = isJobFair.value ? `/pagesB/jobFair/editJob?jobId=${jobId}&jobFairId=${info.value.bizId}` : `/pagesB/positionEdit/index?jobId=${jobId}`
-    uni.navigateTo({ url })
-    // 跳转编辑页面
-  } finally {
-    uni.hideLoading()
-  }
-}
-
-</script>
-
-<style scoped lang="scss">
-@import '../../static/style/position/index.scss';
-.bottom-content {
-  display: flex;
-  justify-content: space-evenly;
-  align-items: center;
-  width: 100%;
-  margin: 20rpx 0;
-  .btnStyle {
-    flex: 1;
-    margin: 0 20rpx;
-  }
-}
-</style>

+ 0 - 23
pagesB/positionEdit/index.vue

@@ -1,23 +0,0 @@
-<template>
-  <view>
-    <position :jobId="jobId" :isClone="isClone"></position>
-  </view>
-</template>
-<script setup>
-import { ref } from 'vue'
-import { onLoad } from '@dcloudio/uni-app'
-import position from '@/components/positionItem'
-
-const jobId = ref('')
-const isClone = ref(false)
-const props = defineProps({
-  jobId: String
-})
-
-onLoad((options) => {
-  jobId.value = options?.jobId || props.jobId || ''
-
-  if (options?.isClone) isClone.value = true
-})
-
-</script>

+ 0 - 147
pagesB/staffInfoEdit/index.vue

@@ -1,147 +0,0 @@
-<template>
-	<view class="f-straight wrapper">
-		<uni-forms ref="form" :modelValue="formData" :rules="rules" validateTrigger="bind" label-width="80px" label-align="right">
-			<uni-forms-item label="头像" name="avatar" class="f-straight" required>
-        <view style="display: flex;flex-wrap: wrap;">
-          <view class="upload-img" v-if="formData?.avatar">
-            <uni-icons size="35" type="clear" color="#fe574a" style="position: absolute;right: -15px; top: -15px; z-index: 9" @click="formData.avatar = ''"></uni-icons>
-            <image :src="formData?.avatar" mode="contain" style="width: 200rpx;height: 200rpx;" @click="handlePreviewImage"></image>
-          </view>
-          <view v-else class="upload-file" @click="uploadPhotos">
-            <uni-icons type="plusempty" size="50" color="#f1f1f1"></uni-icons>
-          </view>
-        </view>
-			</uni-forms-item>
-			<uni-forms-item required label="用户名" name="name">
-        <uni-easyinput v-model="formData.name" placeholder="请输入用户名" />
-			</uni-forms-item>
-      <uni-forms-item label="联系电话" name="phone" clearable required>
-        <uni-easyinput v-model="formData.phone" placeholder="请输入电话号码" />
-			</uni-forms-item>
-      <uni-forms-item label="企业邮箱" name="email" clearable required>
-        <uni-easyinput disabled v-model="formData.email" placeholder="请输入您的企业邮箱" />
-			</uni-forms-item>
-			<uni-forms-item label="所属岗位" name="postName" clearable>
-        <uni-easyinput v-model="formData.postName" placeholder="请输入您所任职的岗位名称" />
-			</uni-forms-item>
-			<view class="f-horizon-center">
-				<button type="primary" size="default" class="send-button"  @click="submit">提 交</button>
-			</view>
-		</uni-forms>
-	</view>
-</template>
-
-<script setup>
-import { ref, unref } from 'vue'
-import { userStore } from '@/store/user'
-import { uploadFile } from '@/api/file'
-import { cloneDeep } from 'lodash-es'
-import { emailRequired } from '@/utils/validate'
-import { updateStaffInfo } from '@/api/enterprise'
-
-const form = ref()
-const useUserStore = userStore()
-
-const formData = ref({})
-const getInfo = () => {
-  formData.value = cloneDeep(useUserStore?.userInfo) || {
-    avatar: '',
-    name: '',
-    phone: '',
-    email: '',
-    postName: ''
-  }
-}
-getInfo()
-
-// 图片预览
-const handlePreviewImage = () => {
-  uni.previewImage({
-    current: 0,
-    urls: [formData.value.avatar]
-  })
-}
-
-// 选择头像
-const uploadPhotos = () => {
-  wx.chooseImage({
-    count: 1,
-    sizeType: ['original', 'compressed'],
-    sourceType: ['album', 'camera'],
-    success: function(res){
-      const size = res.tempFiles[0]?.size || 0
-      if (size >= 31457280) {
-        uni.showToast({
-          icon: 'none',
-          title: '头像上传大小不得超过 20MB !',
-          duration: 2000
-        })
-        return
-      }
-      const path = res.tempFilePaths[0]
-      uploadFile(path, 'img').then(res => {
-        formData.value.avatar = res.data
-      }).catch(error => {
-        uni.showToast({
-          icon: 'error',
-          title: '图片上传失败!',
-          duration: 2000
-        })
-      })
-    }
-  })
-}
-
-const rules = {
-	avatar:{
-		rules: [{required: true, errorMessage: '请上传头像' }]
-	},
-	name:{
-		rules: [{required: true, errorMessage: '请输入您的用户名' }]
-	},
-  email: emailRequired,
-  phone: {
-		rules: [{required: true, errorMessage: '请输入您的联系电话' }]
-	}
-}
-
-const submit = async () => {
-  const valid = await unref(form).validate()
-  if (!valid) return
-  await updateStaffInfo(formData.value)
-
-  uni.showToast({ title: '编辑成功', icon: 'success' })
-  await useUserStore.getUserInfos()
-  getInfo()
-  setTimeout(() => {
-		uni.navigateBack({
-			delta: 1
-		})
-	}, 1000)
-}
-</script>
-
-<style lang="less" scoped>
-
-.wrapper{
-	padding: 15px;
-  padding-top: 30px;
-}
-.upload-img{
-  position: relative;
-  width: 200rpx;
-  height: 200rpx;
-  border: 1px solid #f1f1f1;
-  margin: 10rpx;
-}
-.upload-file{
-  width: 200rpx;
-  height: 200rpx;
-  border: 1px solid #f1f1f1;
-  margin: 10rpx;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  border-radius: 10rpx;
-}
-</style>

BIN
static/img/company-fill.png


BIN
static/img/company.png


BIN
static/img/female.png


BIN
static/img/jobFair-fill.png


BIN
static/img/jobFair.png


BIN
static/img/man.png


BIN
static/img/message-fill.png


BIN
static/img/message.png


BIN
static/img/position-fill.png


BIN
static/img/position.png


BIN
static/img/search-fill.png


BIN
static/img/search.png


BIN
static/img/share-poster.jpg


BIN
static/img/ticket.png


+ 0 - 268
static/style/position/index.css

@@ -1,268 +0,0 @@
-@charset "UTF-8";
-.mb5 {
-  margin-bottom: 5px;
-}
-
-.my5 {
-  margin: 5px 0;
-}
-
-.my10 {
-  margin: 10px 0;
-}
-
-.mt10 {
-  margin-top: 10px;
-}
-
-.fs14 {
-  font-size: 14px;
-}
-
-.fs15 {
-  font-size: 15px;
-}
-
-.box {
-  padding: 10px 30rpx 100px;
-  background-color: #fff;
-}
-
-.shareCss {
-  background-color: #00B760 !important;
-}
-
-.shareCss .box {
-  margin: 20px 24px;
-  border-radius: 10px;
-  background-color: #fff;
-  height: 194px;
-  overflow: hidden;
-}
-
-.JobName {
-  color: #0E100F;
-  font-size: 24px;
-}
-
-.tagList {
-  width: 100%;
-  display: flex;
-  flex-wrap: wrap;
-}
-
-.tagList .tagListItem {
-  margin: 10rpx 10rpx 10rpx 0;
-}
-
-.topLine {
-  border-top: 1px solid #EDEDED;
-  padding-top: 10px;
-}
-
-.tag {
-  padding: 5px 10px;
-  background-color: #e2f0ef;
-  color: #00B760;
-  border-radius: 5px;
-  font-size: 14px;
-  margin-right: 8px;
-  margin-top: 4px;
-}
-
-.hirePrice {
-  padding: 3px 10px;
-  background-color: #e2f0ef;
-  color: #00B760;
-  border-radius: 5px;
-  font-size: 14px;
-  margin-left: 8px;
-}
-
-.htmlCss {
-  white-space: pre-wrap;
-  word-break: break-all;
-  line-height: 28px;
-  color: var(--color-333);
-  font-size: 15px;
-  text-align: justify;
-  letter-spacing: 0;
-}
-
-.bottom-sticky {
-  display: flex;
-  width: 100vw;
-  position: fixed;
-  bottom: 0;
-  left: 0;
-  background-image: linear-gradient(white, white);
-}
-
-.buttons {
-  width: 60vw;
-  height: 44px;
-  border-radius: 25px;
-  margin: 0;
-  background-color: #00B760 !important;
-}
-
-.disable {
-  background-color: #5ec593 !important;
-  color: #ffffec !important;
-}
-
-.noMore {
-  margin: 20px 0;
-}
-
-.date-time {
-  color: #d9d0d2;
-  float: right;
-}
-
-.viewided-line {
-  width: 100%;
-  height: 1px;
-  background-color: #f0f2f7;
-  margin: 20px 0;
-}
-
-.avatarBox {
-  max-width: 40px;
-  max-height: 40px;
-  margin: 0 10px;
-}
-
-.avatar {
-  width: 40px;
-  height: 40px;
-}
-
-.sub-li-bottom {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  background: linear-gradient(90deg, #f5fcfc 0, #fcfbfa 100%);
-  font-size: 13px;
-  padding: 5px 30rpx;
-}
-
-.salary {
-  color: #00B760;
-  line-height: 41px;
-  font-weight: 600;
-  height: auto;
-  display: inline-block;
-  vertical-align: sub;
-}
-
-.list-shape {
-  padding: 10px 30rpx 10px;
-  margin-top: 10px;
-  background-color: #fff;
-}
-
-.list-shape .titleBox {
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-}
-
-.viewider-mx {
-  margin: 0 10rpx;
-}
-
-.viewider {
-  color: #e4d4d2;
-}
-
-.cer-end {
-  position: absolute;
-  top: 85%;
-  right: 16%;
-}
-
-.cer-text {
-  text-decoration: underline;
-  margin: 0 5rpx;
-}
-
-.dis {
-  display: flex;
-  align-items: center;
-}
-
-.showPopup-more {
-  width: 26vw;
-  white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-
-/* 列表触底暂无更多 */
-.noMore {
-  text-align: center;
-  color: grey;
-}
-
-.mt {
-  margin-top: 10rpx;
-}
-
-.mb {
-  margin-bottom: 10rpx;
-}
-
-.ml {
-  margin-left: 20rpx;
-}
-
-.mr {
-  margin-right: 20rpx;
-}
-
-.mr-10 {
-  margin-right: 10rpx;
-}
-
-.my-5 {
-  margin: 5px 0;
-}
-
-.dialogBox .dialog-title {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  color: #767a82;
-  padding: 20rpx;
-}
-
-.dialogBox .dialog-title .title {
-  font-weight: bold;
-  margin-left: 10rpx;
-}
-
-.dialogBox .dialog-content {
-  padding: 20rpx;
-  padding-bottom: 50rpx;
-}
-
-.dialogBox .dialog-content .selected {
-  background-color: #00B760 !important;
-}
-
-.dialogBox .selectOnline {
-  font-size: 14px;
-  color: #00B760;
-  text-align: center;
-  margin-top: 10rpx;
-}
-
-.dialogBox .dialog-bottom {
-  width: 100%;
-  height: 44px;
-  line-height: 44px;
-  text-align: center;
-  color: #fff !important;
-  background-color: #00B760 !important;
-}

File diff suppressed because it is too large
+ 0 - 0
static/style/position/index.min.css


Some files were not shown because too many files changed in this diff