贾宇博 1 mēnesi atpakaļ
vecāks
revīzija
26fc105534
51 mainītis faili ar 4083 papildinājumiem un 302 dzēšanām
  1. 1 1
      .gitignore
  2. 12 0
      api/file.js
  3. 10 0
      api/system/dict.js
  4. 39 0
      api/volunteer.js
  5. 84 0
      components/DictTag/index.vue
  6. 205 0
      components/cust-form/index.vue
  7. 31 0
      components/font-title/index.vue
  8. 36 0
      components/picker/index.vue
  9. 20 0
      components/uni-calendar/changelog.md
  10. 546 0
      components/uni-calendar/components/uni-calendar/calendar.js
  11. 12 0
      components/uni-calendar/components/uni-calendar/i18n/en.json
  12. 8 0
      components/uni-calendar/components/uni-calendar/i18n/index.js
  13. 12 0
      components/uni-calendar/components/uni-calendar/i18n/zh-Hans.json
  14. 12 0
      components/uni-calendar/components/uni-calendar/i18n/zh-Hant.json
  15. 189 0
      components/uni-calendar/components/uni-calendar/uni-calendar-item.vue
  16. 632 0
      components/uni-calendar/components/uni-calendar/uni-calendar.vue
  17. 350 0
      components/uni-calendar/components/uni-calendar/util.js
  18. 85 0
      components/uni-calendar/package.json
  19. 103 0
      components/uni-calendar/readme.md
  20. 124 0
      components/updata-imgs/index.vue
  21. 290 0
      components/wanghexu-timeslot/wanghexu-timeslot.vue
  22. 4 0
      config.js
  23. 1 0
      package.json
  24. 44 7
      pages.json
  25. 152 23
      pages/Client/new_file.vue
  26. 105 271
      pages/classify.vue
  27. 52 0
      pages/order/list/index.vue
  28. 206 0
      pages/order/list/listItem.vue
  29. 193 0
      pages/order/order.vue
  30. 215 0
      pages/register/data.js
  31. 191 0
      pages/register/register.vue
  32. 65 0
      pnpm-lock.yaml
  33. BIN
      static/empty/数据为空.png
  34. BIN
      static/empty/无历史记录.png
  35. BIN
      static/empty/无收藏.png
  36. BIN
      static/empty/无新闻列表.png
  37. BIN
      static/empty/无权限.png
  38. BIN
      static/empty/暂无搜索结果.png
  39. BIN
      static/empty/暂无评论.png
  40. BIN
      static/empty/没有wifi.png
  41. BIN
      static/empty/没有优惠券.png
  42. BIN
      static/empty/没有收货地址.png
  43. BIN
      static/empty/消息为空.png
  44. BIN
      static/empty/消息列表为空.png
  45. BIN
      static/empty/订单为空.png
  46. BIN
      static/empty/购物车为空.png
  47. BIN
      static/empty/页面不存在.png
  48. BIN
      static/img/dd.png
  49. BIN
      static/img/updata-user-img.png
  50. 29 0
      static/scss/global.scss
  51. 25 0
      utils/dict.js

+ 1 - 1
.gitignore

@@ -8,4 +8,4 @@ node_modules
 .idea
 .vscode
 project.private.config.json
-.VSCodeCounter
+.VSCodeCounter

+ 12 - 0
api/file.js

@@ -0,0 +1,12 @@
+import request from '../utils/request'
+
+
+//文件上传
+export function uploadFile(data) {
+    return request({
+        url: `/common/upload`,
+        method: 'post',
+        data: data
+    })
+}
+

+ 10 - 0
api/system/dict.js

@@ -0,0 +1,10 @@
+import request from '@/utils/request'
+
+
+// 根据字典类型查询字典数据信息
+export function getDicts(dictType) {
+    return request({
+      url: '/system/dict/data/type/' + dictType,
+      method: 'get'
+    })
+  }

+ 39 - 0
api/volunteer.js

@@ -0,0 +1,39 @@
+import request from '../utils/request'
+
+//志愿者注册
+export function add(data) {
+    return request({
+        url: `/core/volunteer/info/newVolunteerInfo/${data.serviceCategory}`,
+        method: 'post',
+        data: data
+    })
+}
+
+
+//修改志愿者排班日期
+export function workDate(data) {
+    return request({
+        url: `/core/volunteer/work-date`,
+        method: 'put',
+        data: data
+    })
+}
+
+
+
+//获取志愿者排班日期
+export function getDataTime() {
+    return request({
+        url: `/core/volunteer/work-date/getWorkDateAndTime`,
+        method: 'get',
+    })
+}
+
+//志愿者订单列表
+export function getVolunteerOrderList(data) {
+    return request({
+        url: `/core/users/orders/volunteerOrderList`,
+        method: 'get',
+        params: data
+    })
+}

+ 84 - 0
components/DictTag/index.vue

@@ -0,0 +1,84 @@
+<template>
+  <div>
+    <template v-for="(item, index) in options">
+      <template v-if="values.includes(item.value)">
+        <span
+          v-if="(item.elTagType == 'default' || item.elTagType == '') && (item.elTagClass == '' || item.elTagClass == null)"
+          :key="item.value"
+          :index="index"
+          :class="item.elTagClass"
+        >{{ item.label + " " }}</span>
+        <up-tag
+          v-else
+          :disable-transitions="true"
+          :key="item.value + ''"
+          :index="index"
+          :type="item.elTagType"
+          :class="item.elTagClass"
+          :text="item.label + ''"
+        ></up-tag>
+      </template>
+    </template>
+    <template v-if="unmatch && showValue">
+      {{ unmatchArray | handleArray }}
+    </template>
+  </div>
+</template>
+
+<script setup>
+import { computed, ref } from "vue";
+// 记录未匹配的项
+const unmatchArray = ref([]);
+
+const props = defineProps({
+  // 数据
+  options: {
+    type: Array,
+    default: null,
+  },
+  // 当前的值
+  value: [Number, String, Array],
+  // 当未找到匹配的数据时,显示value
+  showValue: {
+    type: Boolean,
+    default: true,
+  },
+  separator: {
+    type: String,
+    default: ",",
+  }
+});
+
+const values = computed(() => {
+  if (props.value === null || typeof props.value === 'undefined' || props.value === '') return [];
+  return Array.isArray(props.value) ? props.value.map(item => '' + item) : String(props.value).split(props.separator);
+});
+
+const unmatch = computed(() => {
+  unmatchArray.value = [];
+  // 没有value不显示
+  if (props.value === null || typeof props.value === 'undefined' || props.value === '' || !Array.isArray(props.options) || props.options.length === 0) return false
+  // 传入值为数组
+  let unmatch = false // 添加一个标志来判断是否有未匹配项
+  values.value.forEach(item => {
+    if (!props.options.some(v => v.value === item)) {
+      unmatchArray.value.push(item)
+      unmatch = true // 如果有未匹配项,将标志设置为true
+    }
+  })
+  return unmatch // 返回标志的值
+});
+
+function handleArray(array) {
+  if (array.length === 0) return "";
+  return array.reduce((pre, cur) => {
+    return pre + " " + cur;
+  });
+}
+</script>
+
+<style scoped>
+.el-tag + .el-tag {
+  margin-left: 10px;
+}
+</style>

+ 205 - 0
components/cust-form/index.vue

@@ -0,0 +1,205 @@
+<template>
+    <view class="cust-form">
+        <up-form labelPosition="left" :model="formData" ref="form_ref">
+            <view v-for="item in column" :key="item.key + 'cust-form'" class="cust-form-item">
+                <up-form-item v-if="item.type === 'input'" :label="item.label" :prop="item.key" borderBottom
+                    labelWidth="94" :required="item.required">
+                   <up-input v-model="formData[item.key]" border="none" :placeholder="'请输入' + item.label"></up-input>
+                </up-form-item>
+
+                <up-form-item v-if="item.type === 'select'" :label="item.label" :prop="item.key" borderBottom
+                    labelWidth="94" :required="item.required">
+                    <view @click.self="() => openActionSheet(item)">
+                        <up-input v-model="formData[item.key]" disabled disabledColor="#ffffff"
+                            :placeholder="'请选择' + item.label" border="none"></up-input>
+                    </view>
+                    <template #right>
+                        <up-icon name="arrow-right"></up-icon>
+                    </template>
+                </up-form-item>
+
+                <view v-if="item.type === 'phone-code'">
+                    <up-form-item label="手机号" prop="phonenumber" borderBottom labelWidth="94" :rules="[
+                        {
+                            type: 'string',
+                            required: true,
+                            len: 11,
+                            message: '请填写11位手机号',
+                            trigger: ['blur']
+                        }
+                    ]" :required="true">
+                        <up-input v-model="formData.phonenumber" border="none" placeholder="请输入手机号"></up-input>
+                    </up-form-item>
+
+                    <up-form-item label="验证码" prop="code" labelWidth="94" borderBottom :rules="[
+                        {
+                            type: 'string',
+                            required: true,
+                            len: 4,
+                            message: '请填写4位验证码',
+                            trigger: ['blur']
+                        }
+                    ]" :required="true">
+                        <up-input v-model="formData.code" border="none" placeholder="请填写验证码"></up-input>
+                        <template #right>
+                            <up-button @tap="getCode" :text="code_data.tips" type="success" size="mini"
+                                style="flex: 0.5;" :disabled="code_data.disabled"></up-button>
+                        </template>
+
+                    </up-form-item>
+                </view>
+                <up-form-item v-if="item.type === 'textarea'" :label="item.label" :prop="item.key" labelWidth="94" :required="item.required">
+                    <up-textarea :placeholder="'请输入' + item.label" v-model="formData[item.key]" count></up-textarea>
+                </up-form-item>
+
+                <up-form-item v-if="item.type === 'face'" :label="item.label" :prop="item.key" borderBottom
+                    labelWidth="94" :required="item.required">
+                    <up-button size="small" type="primary" text="前往人脸识别" @click="startFace"></up-button>
+                </up-form-item>
+            </view>
+        </up-form>
+        <!-- <up-button type="primary" text="提交" customStyle="margin-top: 50px" @click="onSubmit"></up-button> -->
+
+        <up-action-sheet :show="showSex" :actions="actions.option" :title="'请选择' + actions.label"
+            @close="showSex = false" @select="ActionSheetSelect">
+        </up-action-sheet>
+
+        <up-code ref="uCode" @change="codeChange" seconds="20" @start="code_data.disabled = true"
+            @end="code_data.disabled = false"></up-code>
+    </view>
+</template>
+<script setup>
+import { onMounted, reactive, ref } from "vue";
+
+const props = defineProps({
+    column: {
+        type: Array,
+        default: [],
+    },
+});
+
+const formData = reactive({
+    sex: null,
+    city: null,
+
+    // address: "永川区",
+    // age: "1",
+    // city: "重庆",
+    // code: "1111",
+    // idCard: "5002302000000000001",
+    // name: "陈陈",
+    // phonenumber: "18696601933",
+    // sex: '男',
+    // skillDescribe: "测试备注",
+});
+const form_ref = ref(null);
+
+const showSex = ref(false);
+const actions = ref({
+    option: []
+});
+
+const code_data = reactive({
+    disabled: false,
+    tips: ''
+})
+const uCode = ref(null);
+
+
+function hideKeyboard() {
+    uni.hideKeyboard()
+}
+
+function openActionSheet(row) {
+    console.log(row);
+    hideKeyboard();
+    showSex.value = true;
+    actions.value = row
+}
+
+function ActionSheetSelect(e) {
+    console.log('e', e);
+    Object.assign(formData, {
+        [actions.value.key]: e.key || e.name
+    })
+    console.log('formData.value', formData);
+
+    // form_ref.value.validateField(actions.key)
+}
+
+
+function getCode() {
+    if (uCode.value.canGetCode) {
+        // 模拟向后端请求验证码
+        uni.showLoading({
+            title: '正在获取验证码'
+        })
+        setTimeout(() => {
+            uni.hideLoading();
+            // 这里此提示会被this.start()方法中的提示覆盖
+            uni.$u.toast('验证码已发送');
+            // 通知验证码组件内部开始倒计时
+            uCode.value.start();
+        }, 2000);
+    } else {
+        uni.$u.toast('倒计时结束后再发送');
+    }
+}
+
+function codeChange(text) {
+    code_data.tips = text;
+}
+
+function startFace(){
+    console.log('startFace',formData);
+    
+}
+
+
+function setData(data) {
+    Object.assign(formData, data)
+}
+
+function onSubmit() {
+    // 如果有错误,会在catch中返回报错信息数组,校验通过则在then中返回true
+    return new Promise(async(resolve, reject) => {
+
+        const res = await form_ref.value.validate();
+        if(!res){
+            reject()
+            return
+        }
+        resolve(formData);
+    })
+}
+function onResetField() {
+    form_ref.value.resetFields()
+    form_ref.value.clearValidate()
+}
+onMounted(()=>{
+    const rules = {};
+    for (let i = 0; i < props.column.length; i++) {
+        rules[props.column[i].key] = props.column[i].rules 
+    }
+    form_ref.value && form_ref.value.setRules(rules)
+
+
+    console.log('uni=====>',uni);
+    
+})
+defineExpose({
+    setData,//修改表单数据值
+    onSubmit,//提交表单,先校验再提交
+    onResetField,//表单重置
+})
+</script>
+<style lang="scss" scoped>
+// .cust-form-item{
+//     position: relative;
+// }
+// .required-icon {
+//     color: red;
+//     position: absolute;
+// }
+
+</style>

+ 31 - 0
components/font-title/index.vue

@@ -0,0 +1,31 @@
+<template>
+  <view class="font-title">
+    {{ title }}
+  </view>
+</template>
+  
+  <script>
+export default {
+  data() {
+    return {};
+  },
+  props: {
+    title: {
+      type: String,
+      default: "",
+    },
+  },
+  methods: {},
+};
+</script>
+  
+<style lang="scss" scoped>
+.font-title {
+    font-size: 16px;
+    font-weight: 700;
+    letter-spacing: 0px;
+    line-height: 23.17px;
+    color: rgba(0, 0, 0, 1);
+}
+</style>
+  

+ 36 - 0
components/picker/index.vue

@@ -0,0 +1,36 @@
+<template>
+    <up-picker :show="show" ref="uPickerRef" :columns="columns" @confirm="confirm" @change="changeHandler"></up-picker>
+</template>
+
+<script setup>
+import { ref, reactive } from 'vue';
+
+const show = ref(true);
+const columns = reactive([
+  ['中国', '美国'],
+  ['深圳', '厦门', '上海', '拉萨']
+]);
+const columnData = reactive([
+  ['深圳', '厦门', '上海', '拉萨'],
+  ['得州', '华盛顿', '纽约', '阿拉斯加']
+]);
+
+const uPickerRef = ref(null)
+const changeHandler = (e) => {
+  const {
+    columnIndex,
+    value,
+    values,
+    index,
+  } = e;
+
+  if (columnIndex === 0) {
+    uPickerRef.value.setColumnValues(1, columnData[index]);
+  }
+};
+
+const confirm = (e) => {
+  console.log('confirm', e);
+  show.value = false;
+};
+</script>

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

@@ -0,0 +1,20 @@
+## 1.4.7(2022-09-16)
+- 可以使用 uni-scss 控制主题色
+## 1.4.6(2022-09-08)
+- fix: 表头年月切换,导致改变当前日期为选择月1号,且未触发change事件
+## 1.4.5(2022-02-25)
+- 修复 条件编译 nvue 不支持的 css 样式
+## 1.4.4(2022-02-25)
+- 修复 条件编译 nvue 不支持的 css 样式
+## 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": "六"
+}

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

@@ -0,0 +1,189 @@
+<template>
+	<view class="uni-calendar-item__weeks-box" :class="{
+		'uni-calendar-item--disable':weeks.disable,
+		'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,
+		}"
+	 @click="choiceDate(weeks)">
+		<view class="uni-calendar-item__weeks-box-item">
+			<text v-if="selected&&weeks.extraInfo" 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.extraInfo && 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&&!weeks.extraInfo" 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>
+</template>
+
+<script>
+	import {
+	initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import messages from './i18n/index.js'
+	const {	t	} = initVueI18n(messages)
+	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:9px;
+	$uni-color-error: #0dda5f;
+	$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;
+	}
+
+	.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;
+	}
+
+	.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 !important;
+	}
+
+	.uni-calendar-item--extra {
+		// color: $uni-color-error;
+		color: $uni-primary;
+		opacity: 0.8;
+	}
+
+	.uni-calendar-item--checked {
+		// background-color: $uni-primary;
+		// color: #fff;
+		// opacity: 0.8;
+	}
+
+	.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>

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

@@ -0,0 +1,632 @@
+<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-swich">
+					<view class="swi-lable">单选</view>
+					<up-switch  v-model="switchValue" @change="onSwichChange"></up-switch>
+					<view class="swi-lable">多选</view>
+					
+					</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>
+
+			<timeSlot 
+				ref="timeslot"
+				:title="'选择时间段'"
+				@confirm="confirmTime" />
+		</view>
+	</view>
+</template>
+
+<script>
+	import Calendar from './util.js';
+	import calendarItem from './uni-calendar-item.vue'
+	import {
+	initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import messages from './i18n/index.js'
+	import timeSlot from "../../../wanghexu-timeslot/wanghexu-timeslot.vue"
+	import { ref, toRaw } from 'vue';
+	const {	t	} = initVueI18n(messages)
+	/**
+	 * 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` 时生效
+	 * @example <uni-calendar :insert="true":lunar="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" />
+	 * @property {String} mode 模式 multiple:多选 single 默认单选
+	 */
+	export default {
+		components: {
+			calendarItem,
+			timeSlot
+		},
+		emits:['close','confirm','change','monthSwitch','delete'],
+		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
+			},
+			mode: {
+				type: String,
+				default: 'single'
+			}
+		},
+		data() {
+			return {
+				show: false,
+				weeks: [],
+				calendar: {},
+				nowDate: '',
+				aniMaskShow: false,
+				cheackDates:[],
+				startTime:'',
+				endTime:'',
+				switchValue:false,
+				datas:[]
+			}
+		},
+		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) {
+				console.log('xx',newVal);
+				
+				this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
+				this.weeks = this.cale.weeks
+			}
+		},
+		created() {
+			this.calendarinit();
+		},
+		methods: {
+			calendarinit() {
+				// 获取日历方法实例
+				this.cale = new Calendar({
+					selected: this.selected,
+					startDate: this.startDate,
+					endDate: this.endDate,
+					range: this.switchValue,
+				})
+				// 选中某一天
+				// this.cale.setDate(this.date)
+				this.init(this.date)
+
+			},
+			// 取消穿透
+			clean() {},
+			bindDateChange(e) {
+				const value = e.detail.value + '-1'
+				console.log(this.cale.getDate(value));
+				this.setDate(value)
+			},
+			/**
+			 * 初始化日期显示
+			 * @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() {
+				console.log('变化触发',this.cale,this.calendar.fullDate);
+				if(this.switchValue && !this.cale.multipleStatus.after){
+					return;
+				}
+				const  is_select =  this.selected.filter(item => {
+					console.log(3,item,item.data,this.calendar.fullDate,);
+					return item.date===this.calendar.fullDate
+				})
+				
+				if(is_select && is_select.length> 0){
+					console.log('is_select',is_select);
+					this.setEmit('delete')
+					return;
+				}
+				
+				this.$refs.timeslot.bindstartChange({detail:{value:[9,0]}})
+				this.$refs.timeslot.bindendChange({detail:{value:[18,0]}})
+				this.$refs.timeslot.open();
+
+			},
+			/**
+			 * 选择月份触发
+			 */
+			monthSwitch() {
+				let {
+					year,
+					month
+				} = this.nowDate
+				this.$emit('monthSwitch', {
+					year,
+					month: Number(month)
+				})
+			},
+			/**
+			 * 派发事件
+			 * @param {Object} name
+			 */
+			setEmit(name) {
+				let {
+					year,
+					month,
+					date,
+					fullDate,
+					lunar,
+					extraInfo,
+				} = this.calendar
+				this.$emit(name, {
+					range: this.cale.multipleStatus,
+					year,
+					month,
+					date,
+					fulldate: fullDate,
+					lunar,
+					extraInfo: extraInfo || {},
+					time:{
+						startTime: this.startTime,
+						endTime: this.endTime
+					}
+				})
+			},
+			/**
+			 * 选择天触发
+			 * @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() {
+				console.log(this.cale.getDate(new Date()).fullDate);
+				let date = this.cale.getDate(new Date()).fullDate
+				// this.cale.setDate(date)
+				this.init(date)
+				this.change()
+			},
+			/**
+			 * 上个月
+			 */
+			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)
+			},
+			confirmTime(e){
+				this.startTime = e.start.hour+":" + e.start.min;
+				this.endTime = e.end.hour+":" + e.end.min;
+				this.setEmit('change')
+			},
+			onSwichChange(e){
+				console.log('change', e);
+				this.calendarinit();
+			}
+		}
+	}
+</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;
+		// padding: 0 15px;
+	}
+	.uni-calendar__start {
+		position: absolute;
+		left: 25rpx;
+		top: 25rpx;
+		font-size: 12px;
+	}
+	.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 */
+	}
+	.uni-calendar__header-btn-swich {
+		display: flex;
+		align-content: center;
+	}
+	.swi-lable {
+		margin: 0 6px;
+	}
+</style>

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

@@ -0,0 +1,350 @@
+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) {
+					dd.setDate(dd.getDate() + AddDayCount)
+				} else {
+					dd.setMonth(dd.getMonth() + AddDayCount) // 获取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.7",
+  "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)

+ 124 - 0
components/updata-imgs/index.vue

@@ -0,0 +1,124 @@
+<template>
+    <view class="updata-img">
+        <view class="updata-title-box">
+            <view class="updata-title-title font-title ">{{ data.title }} <span style="color: #f56c6c;" v-if="data.required">*</span> </view>
+            <view class="updata-title-text font-text ">{{ data.text }}</view>
+        </view>
+        <view class="updata-img-box" @click="updataFile">
+
+            <image :src="img" style="width: 117px;height: 75px;" />
+            <!-- <up-upload :fileList="fileList" @afterRead="afterRead"  name="1" multiple :maxCount="1">
+                <image :src="img"  style="width: 117px;height: 75px;" />
+            </up-upload> -->
+        </view>
+    </view>
+</template>
+
+<script setup>
+import { ref, toRaw } from 'vue';
+import { uploadFile } from '../../api/file';
+import { getToken } from '@/utils/auth'
+import config from '@/config'
+const baseUrl = config.baseUrl
+
+const props = defineProps({
+    data: {
+        type: Object,
+        default: {
+            title: '上传头像',
+            text: '上传您的头像',
+            img: "/static/img/updata-user-img.png"
+        },
+    },
+});
+const emit = defineEmits(['onSubmit']);
+
+const file = ref(null);
+
+const img = ref(props.data.img);
+
+function updataFile() {
+
+    wx.chooseMessageFile({
+        count: 1,
+        type: 'file',
+        success: (res) => {
+            {
+                const tempFilePath = res.tempFiles[0].path;  // 获取临时文件路径     
+                const fs = wx.getFileSystemManager();  // 获取文件系统管理器 
+
+                wx.uploadFile({
+                    url: baseUrl + '/common/upload',  // 服务器接口地址 
+                    filePath: tempFilePath,        // 本地文件路径(通过 wx.chooseImage  获取)
+                    name: 'file',                      // 文件对应的 key(服务器接收字段名)
+                    formData: {                        // 额外表单数据 
+                        file: res.tempFiles[0],
+                    },
+                    header: {
+                        'Authorization': 'Bearer ' + getToken(),   // 自定义请求头
+                    },
+                    success(res) {
+                        const data = JSON.parse(res.data);
+                        file.value = data.url;                        
+                        emit('onSubmit',{key: props.data.key,url: data.url})
+                        fs.readFile({
+                            filePath: tempFilePath,
+                            encoding: 'base64', // 指定编码格式 
+                            success: (fileRes) => {
+                                const base64Data = 'data:image/png;base64,' + fileRes.data;  // 拼接 Base64 前缀 
+                                img.value = base64Data;
+                                uni.showToast({
+                                    title: '上传成功',
+                                    icon: 'none'
+                                })
+                            },
+                            fail: (err) => {
+                                uni.showToast({
+                                    title: '上传失败',
+                                    icon: 'none'
+                                })
+                                console.error(' 转换失败:', err);
+                            }
+                        });
+                    },
+                    fail(error) {
+                        console.log(' 上传失败', error);
+                        uni.showToast({
+                            title: '上传失败',
+                            icon: 'none'
+                        })
+                    }
+                });
+
+            }
+        }
+    });
+}
+
+function getFile() {
+    return toRaw(file.value);
+}
+defineExpose({
+    getFile,
+});
+</script>
+
+<style lang="scss" scoped>
+.updata-img {
+    border-radius: 8px;
+    background: rgba(255, 255, 255, 1);
+    height: 100px;
+    padding: 16px;
+
+    display: flex;
+    align-content: center;
+    justify-content: space-between;
+
+    .updata-title-box {
+        display: flex;
+        align-content: center;
+        flex-direction: column;
+        justify-content: space-evenly;
+    }
+}
+</style>

+ 290 - 0
components/wanghexu-timeslot/wanghexu-timeslot.vue

@@ -0,0 +1,290 @@
+<template>
+    <view>
+		<view v-if="isShow" class="time_mask" :class="{'uni-timer-mask-show':timeMaskShow}"></view>
+		<view v-if="isShow" class="yx_time_slot" :class="{'fadelogIn1':timeMaskShow}">
+			<view class="time_top_box">
+				<view class="time_close" @click="close">取消</view>
+				<view class="time_text">{{title}}</view>
+				<view class="time_comfirm" @click="confirm">确认</view>
+			</view>
+			<view class="typelist">
+				<view class="typeobj" :class="{'typeobj_hover':typeIndex==index}" v-for="(item,index) in typeList" :key="index" @click="handleType(index)">
+					<view class="text">{{item}}</view>
+					<view class="line"></view>
+				</view>
+			</view>
+			<!-- 时间选择 -->
+			<view class="yx_timer_sel">
+				<swiper class="sel_swiper" :current="typeIndex">
+				    <swiper-item>
+				        <view>
+							<picker-view :value="startvalue" :indicator-style="indicatorStyle" @change="bindstartChange" class="sel_swiper-item">
+							    <picker-view-column>
+							        <view class="item" v-for="(item,index) in timeHour" :key="index">{{item}}时</view>
+							    </picker-view-column>
+							    <picker-view-column>
+							        <view class="item" v-for="(item,index) in timeMin" :key="index">{{item}}分</view>
+							    </picker-view-column>
+							</picker-view>
+						</view>
+				    </swiper-item>
+				    <swiper-item>
+				        <view>
+				    		<picker-view :value="endvalue" :indicator-style="indicatorStyle" @change="bindendChange" class="sel_swiper-item">
+				    		    <picker-view-column>
+				    		        <view class="item" v-for="(item,index) in timeHour" :key="index">{{item}}时</view>
+				    		    </picker-view-column>
+				    		    <picker-view-column>
+				    		        <view class="item" v-for="(item,index) in timeMin" :key="index">{{item}}分</view>
+				    		    </picker-view-column>
+				    		</picker-view>
+				    	</view>
+				    </swiper-item>
+				</swiper>
+			</view>
+			
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	name:"time_slot",
+	props: {
+		title: {
+		    type: String,
+		    default: () => {
+		       return "选择时间段";
+		    }
+		},
+	},
+    data() {
+        return {
+			timeMaskShow:false,//遮罩
+			isShow:false,//显示
+			typeList:["开始时间","结束时间"],
+			typeIndex:0,//下标
+			startvalue:[14,0],//默认下标,14时 00分
+			endvalue:[15,0],//默认下标,15时 00分
+			indicatorStyle: 'height: 50px;',
+			// timeList:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23],
+			timeHour:[],
+			timeMin:[],//分钟可选项
+        };
+    },
+    mounted() {
+		//获取时分
+		let timeHour = [] 
+		let timeMin = [] 
+		for (let i = 0; i < 24; i++) {
+		    timeHour.push(this.formatNumber(i))
+	    }
+		for (let i = 0; i < 60; i++) {
+		    timeMin.push(this.formatNumber(i))
+		}
+		this.timeHour = timeHour
+		this.timeMin = timeMin
+	},
+    methods: {
+		//看看是不是有两位数
+		formatNumber(n) {
+			n = n.toString()
+			return n[1] ? n : '0' + n
+		},
+		//开始选择
+		bindstartChange(e){
+			console.log('开始选择',e)
+			this.startvalue = e.detail.value
+		},
+		//结束选择
+		bindendChange(e){
+			console.log(e)
+			this.endvalue = e.detail.value
+		},
+        /**
+         * 关闭弹窗
+         */
+        close() {
+        	this.timeMaskShow = false
+        	this.$nextTick(() => {
+        		setTimeout(() => {
+        			this.isShow = false
+        			this.$emit('close')
+        		}, 300)
+        	})
+        },
+        /**
+         * 确认按钮
+         */
+        confirm() {
+			if(this.typeIndex==0){
+				this.endvalue = [this.startvalue[0]+1,0]
+				this.typeIndex = 1
+			}else{
+				if(this.startvalue[0]<this.endvalue[0] || (this.startvalue[0]==this.endvalue[0]&&this.startvalue[1]<this.endvalue[1])){
+					var obj = {
+						start:{
+							hour:this.timeHour[this.startvalue[0]],
+							min:this.timeMin[this.startvalue[1]]
+						},
+						end:{
+							hour:this.timeHour[this.endvalue[0]],
+							min:this.timeMin[this.endvalue[1]]
+						}
+					}
+					this.$emit('confirm',obj)
+					this.close()
+				}else{
+					uni.showToast({
+						icon:"error",
+						title:"结束时间要大于开始时间"
+					})
+				}
+				
+			}
+        },
+		/**
+		 * 打开日历弹窗
+		 */
+		open() {
+			this.typeIndex = 0
+			this.isShow = true
+			this.$nextTick(() => {
+				setTimeout(() => {
+					this.timeMaskShow = true
+				}, 50)
+			})
+		},
+		//栏目选择
+		handleType(index){
+			if(index!=this.typeIndex){
+				if(index==1){
+					this.endvalue = [this.startvalue[0]+1,0]
+				}
+				this.typeIndex = index
+			}
+		},
+		setTime(time){
+			console.log('time',time);
+			
+			this.startvalue = time.start;
+			this.endvalue = time.end;
+		}
+		
+    }
+};
+</script>
+
+<style lang="scss" scoped>
+.time_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: 10076;
+	/* #endif */
+}
+.yx_time_slot{
+	background-color: #FFFFFF;
+	width: 100%;
+	height: 750rpx;
+	position: fixed;
+	bottom: calc(var(--window-bottom));
+	left: 0;
+	right: 0;
+	z-index: 10077;
+	transition-property: transform;
+	transition-duration: 0.3s;
+	transform: translateY(460px);
+	.time_top_box{
+		width: 100%;
+		height: 80rpx;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		.time_close,.time_comfirm{
+			width: 100rpx;
+			color: #999999;
+			font-size: 28rpx;
+			font-weight: 400;
+			text-align: center;
+		}
+		.time_comfirm{
+			color: #4360F7;
+		}
+		.time_text{
+			flex: 1;
+			font-size: 30rpx;
+			font-weight: 800;
+			text-align: center;
+		}
+	}
+}
+.uni-timer-mask-show{
+	opacity: 1;
+}
+/* 从下往上弹窗动画 */
+.fadelogIn1 {
+	// -webkit-animation: fadelogIn 0.5s;
+	// animation: fadelogIn 0.5s;
+	transform: translateY(0);
+}
+.typelist{
+	width: 100%;
+	height: 70rpx;
+	display: flex;
+	align-items: center;
+	.typeobj{
+		width: 158rpx;
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		.text{
+			height: 65rpx;
+			line-height: 65rpx;
+			font-size: 28rpx;
+			color: #333333;
+		}
+		.line{
+			width: 1rpx;
+			height: 5rpx;
+		}
+	}
+	.typeobj_hover{
+		.text{
+			font-weight: 600;
+		}
+		.line{
+			width: 88rpx;
+			transition: width .5s;
+			background-color: #4360F7;
+		}
+	}
+}
+.yx_timer_sel{
+	width: 100%;
+	margin-top: 38rpx;
+	.sel_swiper{
+		// width: 80%;
+		// margin: 0 auto;
+		height: 500rpx;
+	}
+	.sel_swiper-item{
+		height: 500rpx;
+		.item {
+		    height: 50px;
+			display: flex;
+		    align-items: center;
+		    justify-content: center;
+		    text-align: center;
+		}
+	}
+}
+</style>

+ 4 - 0
config.js

@@ -3,7 +3,11 @@ const config = {
 	// baseUrl: 'https://vue.ruoyi.vip/prod-api',
 	//cloud后台网关地址
 	// baseUrl: 'http://192.168.10.3:8080',
+<<<<<<< HEAD
 	baseUrl: 'http://192.168.100.114:9527',
+=======
+	baseUrl: 'http://192.168.100.102:9527',
+>>>>>>> e304b330bbea412ab178beebd8b9788292f4e724
 	// 应用信息
 	appInfo: {
 		// 应用名称

+ 1 - 0
package.json

@@ -10,6 +10,7 @@
   "author": "",
   "license": "ISC",
   "dependencies": {
+    "dayjs": "^1.11.13",
     "uview-plus": "^3.4.9"
   }
 }

+ 44 - 7
pages.json

@@ -72,7 +72,44 @@
 			"style": {
 				"navigationBarTitleText": "详情"
 			}
+<<<<<<< HEAD
 		}        
+=======
+		},
+		{
+			"path" : "pages/register/register",
+			"style" : 
+			{
+				"navigationBarTitleText" : "注册"
+			}
+		},
+		{
+			"path" : "pages/order/order",
+			"style" : 
+			{
+				"navigationBarTitleText" : ""
+			}
+		}
+	    
+        // ,{
+        //     "path" : "components/Volunteerside/Volunteerside",
+        //     "style" :                                                                                    
+        //     {
+        //         "navigationBarTitleText": "",
+        //         "enablePullDownRefresh": false
+        //     }
+            
+        // }
+        // ,{
+        //     "path" : "static/imageDetails/imageDetails",
+        //     "style" :                                                                                    
+        //     {
+        //         "navigationBarTitleText": "",
+        //         "enablePullDownRefresh": false
+        //     }
+            
+        // }
+>>>>>>> e304b330bbea412ab178beebd8b9788292f4e724
     ],
 	"subPackages": [
 		{
@@ -287,17 +324,17 @@
 				"selectedIconPath": "static/images/tabbar/home_.png",
 				"text": "首页"
 			},
-			{
-				"pagePath": "pages/work",
-				"iconPath": "static/images/tabbar/work.png",
-				"selectedIconPath": "static/images/tabbar/work_.png",
-				"text": "工作台"
-			},
+			// {
+			// 	"pagePath": "pages/work",
+			// 	"iconPath": "static/images/tabbar/work.png",
+			// 	"selectedIconPath": "static/images/tabbar/work_.png",
+			// 	"text": "工作台"
+			// },
 			{
 				"pagePath": "pages/classify",
 				"iconPath": "static/images/tabbar/work.png",
 				"selectedIconPath": "static/images/tabbar/work_.png",
-				"text": "分类"
+				"text": "订单"
 			},
 			{
 				"pagePath": "pages/mine",

+ 152 - 23
pages/Client/new_file.vue

@@ -8,16 +8,16 @@
 						:custom-style="{ padding: '20rpx' }">
 						<!-- 图标 -->
 						<image :src="item.icon" class="service-img" mode="aspectFit" />
-		
+
 						<!-- 文本 -->
 						<text class="grid-text">{{ item.name }}</text>
 					</up-grid-item>
 				</up-grid>
-		
+
 				<up-toast ref="uToastRef" />
 			</view>
 		</template>
-		
+
 		<template v-else-if="userType == 2">
 			<view class="Wrapper-grid">
 				<up-grid :border="false" col="4" @click="handleGridClick">
@@ -25,32 +25,62 @@
 						:custom-style="{ padding: '20rpx' }">
 						<!-- 图标 -->
 						<image :src="item.icon" class="service-img" mode="aspectFit" />
-		
+
 						<!-- 文本 -->
-						<text class="grid-text">111{{ item.name }}</text>
+						<text class="grid-text">{{ item.name }}</text>
 					</up-grid-item>
 				</up-grid>
-		
+
 				<up-toast ref="uToastRef" />
 			</view>
 		</template>
+
+		<Calendar ref="calendar" class="uni-calendar--hook" :clear-date="false" :date="info.date" :insert="info.insert"
+			:lunar="info.lunar" :range="info.range" @change="change" :clearDate="true"
+			@confirm="confirm" :selected="selected" @delete="onDelete"/>
+
+
 	</view>
+
 </template>
 
 <script setup>
 	import {
 		ref,
-		onMounted
+		onMounted,
+		watch,
+		computed
 	} from 'vue';
 	import {
 		typeOptionSelect
 	} from "@/api/volunteerDetailsApi/details.js"
+<<<<<<< HEAD
 	
 	// Toast 控制宫格
 	const uToastRef = ref(null);
 	const userType = uni.getStorageSync('userType') //读取本地存储
 	// 用户/志愿者 识别标识
 	const userOrWorker = uni.getStorageSync('storage_data').vuex_userOrWorker //读取本地存储
+=======
+	import dayjs from 'dayjs';
+	import { workDate,getDataTime } from '@/api/volunteer.js'
+	import Calendar from '../../components/uni-calendar/components/uni-calendar/uni-calendar.vue'
+
+	// Toast 控制宫格
+	const uToastRef = ref(null);
+	const userType = uni.getStorageSync('userType') //读取本地存储
+
+	const calendar = ref(null)
+	const info = ref({
+		lunar: true,
+		range: true,
+		insert: false,
+	})
+	const selected = ref([])
+
+
+
+>>>>>>> e304b330bbea412ab178beebd8b9788292f4e724
 	 // 普通用户
 	 const serviceList1 = ref([
 		 {
@@ -81,45 +111,144 @@
 	 //志愿者
 	 const serviceList2 = ref([{
 	 		icon: '/static/img/统一知识平台-营运@1x.png',
-	 		name: '家庭辅导注册'
+	 		name: '家庭辅导注册',
+			key:2,
 	 	},
 	 	{
 	 		icon: '/static/img/编组.png',
-	 		name: '陪伴陪聊注册'
+	 		name: '陪伴陪聊注册',
+			key:1,
 	 	},
 	 	{
 	 		icon: '/static/img/清空.png',
-	 		name: '家庭助理注册'
+	 		name: '家庭助理注册',
+			key:3,
 	 	},
 	 	{
 	 		icon: '/static/img/构建.png',
-	 		name: '健康管理注册'
+	 		name: '健康管理注册',
+			key:4
 	 	},
 	 	{
 	 		icon: '/static/img/报事报修@6x.png',
-	 		name: '家庭清洁注册'
+	 		name: '家庭清洁注册',
+			key:5
 	 	},
 	 	{
 	 		icon: '/static/img/报事报修@6x.png',
-	 		name: '家务帮手注册'
+	 		name: '家务帮手注册',
+			key:6
 	 	},
 	 	{
 	 		icon: '/static/img/清空.png',
-	 		name: '时间管理'
+	 		name: '排班管理',
+			key:7
 	 	},
 	 ]);
 	 
 	
-	// 宫格点击事件
-	const handleGridClick = async() => {
-		console.log("y页面初始化")
+// 宫格点击事件
+const handleGridClick = async (index) => {
+	console.log('userType', userType);
+
+	if (userType == 1) {
 		const res = await typeOptionSelect()
-		console.log((res,'获取健值成功'))
-		 uni.navigateTo({
-		     url: '/pages_home/pages/client/details'
-		   });
-	};
-	
+		console.log((res, '获取健值成功'))
+		uni.navigateTo({
+			url: '/pages_home/pages/client/details'
+		});
+		return
+	}
+	if (uToastRef.value) {
+		const data = serviceList2.value[index]
+		if (data.key !== 7) {
+			uni.navigateTo({
+				url: `/pages/register/register?data=${encodeURIComponent(JSON.stringify(data))}`
+			});
+			return;
+		}
+		calendar.value.open();
+	}
+};
+
+
+const change = (e) => {
+	console.log('change', e);
+	let dates = [{
+		date: e.fulldate,
+		info: `${e.time.startTime}~${e.time.endTime}`,
+		time: e.time
+	}]
+	if (e.range.before && e.range.after) {
+		dates = e.range.data.map(item => {
+			return {
+				date: item,
+				info: `${e.time.startTime}~${e.time.endTime}`,
+				time: e.time
+			}
+		})
+	}
+	selected.value = [...selected.value, ...dates]
+}
+
+const onDelete = (e) =>{
+	selected.value = selected.value.filter(item => {
+		console.log('item.fulldate !== e.date',item.date , e.fulldate);
+		
+		return item.date !== e.fulldate
+	})
+	console.log(e,selected.value);	
+}
+const confirm = (e) => {
+	const parmas = selected.value.map(item => {
+		return {
+			workDate: item.date,
+			workStartTime: item.time.startTime,
+			workEndTime: item.time.endTime
+		}
+	})
+	console.log('确定', parmas);
+	workDate(parmas).then(res => {
+		if (res.code == 200) {
+			uni.showToast({
+				title: '修改成功',
+				icon: 'none'
+			})
+			close();
+			return;
+		}
+		uni.showToast({
+			title: res.msg,
+			icon: 'none'
+		})
+	})
+};
+const close = () => {
+	calendar.value.close();
+}
+
+const init = () => {
+	getDataTime().then(res => {
+		console.log('res', res);
+		selected.value = res.data.map(item =>{
+			return {
+				date: item.workDate,
+				info: `${item.workStartTime}~${item.workEndTime}`,
+				time: {
+					startTime: item.workStartTime,
+					endTime: item.workEndTime
+				}
+			}
+		})
+
+	})
+}
+
+
+
+onMounted(() => {
+	init();
+});
 </script>
 
 <style scoped>

+ 105 - 271
pages/classify.vue

@@ -1,293 +1,127 @@
 <template>
-	<view class="u-wrap">
-		<view class="u-search-box">
-			<view class="u-search-inner">
-				<u-icon name="search" color="#909399" :size="28"></u-icon>
-				<text class="u-search-text">搜索</text>
+	<view class="classify-main">
+		<up-tabs :list="column" :scrollable="false" @change="onChange" :activeStyle="{
+			color: 'rgba(255, 87, 4, 1)',
+			fontWeight: 'bold',
+			transform: 'scale(1.05)'
+		}" lineColor="rgba(255, 87, 4, 1)">
+		</up-tabs>
+		<view class="list">
+			<List :data="data" @refresh="getList" v-if="data.length > 0" />
+
+			<view v-else class="empty-null">
+				<img src="/static/empty/订单为空.png" alt="">
 			</view>
 		</view>
-		<view class="u-menu-wrap">
-			<scroll-view scroll-y scroll-with-animation class="u-tab-view menu-scroll-view" :scroll-top="scrollTop"
-				:scroll-into-view="itemId">
-				<view v-for="(item, index) in tabbar" :key="index" class="u-tab-item"
-					:class="[current == index ? 'u-tab-item-active' : '']" @tap.stop="swichMenu(index)">
-					<text class="u-line-1">{{ item.name }}</text>
-				</view>
-			</scroll-view>
-			<scroll-view :scroll-top="scrollRightTop" scroll-y scroll-with-animation class="right-box"
-				@scroll="rightScroll">
-				<view class="page-view">
-					<view class="class-item" :id="'item' + index" v-for="(item, index) in tabbar" :key="index">
-						<view class="item-title">
-							<text>{{ item.name }}</text>
-						</view>
-						<view class="item-container">
-							<view class="thumb-box" v-for="(item1, index1) in item.foods" :key="index1"
-								@click="clickMenu(item1)">
-								<image class="item-menu-image" :src="item1.icon" mode=""></image>
-								<view class="item-menu-name">{{ item1.name }}</view>
-							</view>
-						</view>
-					</view>
-				</view>
-			</scroll-view>
-		</view>
+
 	</view>
 </template>
-<script>
-import classifyData from '@/pages_template/common/classify.data.js';
-export default {
-	data() {
-		return {
-			scrollTop: 0, //tab标题的滚动条位置
-			oldScrollTop: 0,
-			current: 0, // 预设当前项的值
-			menuHeight: 0, // 左边菜单的高度
-			menuItemHeight: 0, // 左边菜单item的高度
-			itemId: '', // 栏目右边scroll-view用于滚动的id
-			tabbar: classifyData,
-
-			arr: [],
-			scrollRightTop: 0, // 右边栏目scroll-view的滚动条高度
-			timer: null, // 定时器
 
-		}
+<script setup>
+import { ref } from 'vue';
+import List from './order/list/index.vue';
+import { provide } from 'vue';
+import { getVolunteerOrderList } from '@/api/volunteer.js'
+import { onMounted } from 'vue';
+import {useDict} from '@/utils/dict.js';
+
+const { lrr_service_category, lrr_chitchat,lrr_study,order_status } = useDict('lrr_service_category','lrr_chitchat','lrr_study','order_status');
+provide('lrr_service_category', lrr_service_category); //服务类别
+provide('lrr_chitchat', lrr_chitchat);//陪伴陪聊
+provide('lrr_study', lrr_study);//家庭辅导
+provide('order_status', order_status);//订单/服务状态
+
+
+const tab = ref({});
+const data = ref([]);
+
+/**
+ * 	0待支付 1已支付 2支付超时或取消 3进行中 4已完成 5申请退款中 6已退款 7部分退款 8 待确认
+ */
+const column = [
+	{
+		name: "全部",
+		value: "",
+	},
+	{
+		name: "待服务",
+		value: "1",
+	},
+	{
+		name: "进行中",
+		value: "3",
 	},
-	onReady() {
-		this.getMenuItemTop()
+	{
+		name: "已完成",
+		value: "4",
 	},
-	methods: {
-		// 点击左边的栏目切换
-		async swichMenu(index) {
-			if (this.arr.length == 0) {
-				await this.getMenuItemTop();
-			}
-			if (index == this.current) return;
-			this.scrollRightTop = this.oldScrollTop;
-			this.$nextTick(() => {
-				this.scrollRightTop = this.arr[index];
-				this.current = index;
-				this.leftMenuStatus(index);
-			})
-		},
-		// 获取一个目标元素的高度
-		getElRect(elClass, dataVal) {
-			new Promise((resolve, reject) => {
-				const query = uni.createSelectorQuery().in(this);
-				query.select('.' + elClass).fields({
-					size: true
-				}, res => {
-					// 如果节点尚未生成,res值为null,循环调用执行
-					if (!res) {
-						setTimeout(() => {
-							this.getElRect(elClass);
-						}, 10);
-						return;
-					}
-					this[dataVal] = res.height;
-					resolve();
-				}).exec();
-			})
-		},
-		// 观测元素相交状态
-		async observer() {
-			this.tabbar.map((val, index) => {
-				let observer = uni.createIntersectionObserver(this);
-				// 检测右边scroll-view的id为itemxx的元素与right-box的相交状态
-				// 如果跟.right-box底部相交,就动态设置左边栏目的活动状态
-				observer.relativeTo('.right-box', {
-					top: 0
-				}).observe('#item' + index, res => {
-					if (res.intersectionRatio > 0) {
-						let id = res.id.substring(4);
-						this.leftMenuStatus(id);
-					}
-				})
-			})
-		},
-		// 设置左边菜单的滚动状态
-		async leftMenuStatus(index) {
-			this.current = index;
-			// 如果为0,意味着尚未初始化
-			if (this.menuHeight == 0 || this.menuItemHeight == 0) {
-				await this.getElRect('menu-scroll-view', 'menuHeight');
-				await this.getElRect('u-tab-item', 'menuItemHeight');
-			}
-			// 将菜单活动item垂直居中
-			this.scrollTop = index * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight / 2;
-		},
-		// 获取右边菜单每个item到顶部的距离
-		getMenuItemTop() {
-			new Promise(resolve => {
-				let selectorQuery = uni.createSelectorQuery();
-				selectorQuery.selectAll('.class-item').boundingClientRect((rects) => {
-					// 如果节点尚未生成,rects值为[](因为用selectAll,所以返回的是数组),循环调用执行
-					if (!rects.length) {
-						setTimeout(() => {
-							this.getMenuItemTop();
-						}, 10);
-						return;
-					}
-					rects.forEach((rect) => {
-						// 这里减去rects[0].top,是因为第一项顶部可能不是贴到导航栏(比如有个搜索框的情况)
-						this.arr.push(rect.top - rects[0].top);
-						resolve();
-					})
-				}).exec()
-			})
-		},
-		// 右边菜单滚动
-		async rightScroll(e) {
-			this.oldScrollTop = e.detail.scrollTop;
-			if (this.arr.length == 0) {
-				await this.getMenuItemTop();
-			}
-			if (this.timer) return;
-			if (!this.menuHeight) {
-				await this.getElRect('menu-scroll-view', 'menuHeight');
-			}
-			setTimeout(() => { // 节流
-				this.timer = null;
-				// scrollHeight为右边菜单垂直中点位置
-				let scrollHeight = e.detail.scrollTop + this.menuHeight / 2;
-				for (let i = 0; i < this.arr.length; i++) {
-					let height1 = this.arr[i];
-					let height2 = this.arr[i + 1];
-					// 如果不存在height2,意味着数据循环已经到了最后一个,设置左边菜单为最后一项即可
-					if (!height2 || scrollHeight >= height1 && scrollHeight < height2) {
-						this.leftMenuStatus(i);
-						return;
-					}
-				}
-			}, 10)
-		},
-		clickMenu(menu) {
-			console.log(menu);
-		}
+	{
+		name: "已取消",
+		value: "2",
+	}
+]
+
+async function getList(parmas) {
+	console.log('getList', parmas);
+	try {
+		uni.hideLoading();
+		uni.showLoading({
+			title: '数据加载中...'
+		});
+		const res = await getVolunteerOrderList({ orderStatus: tab.value.value });
+		data.value = res.data;
+	} catch (error) {
+		console.log('error', error);
+		uni.showToast({
+			title: error.msg,
+			icon: 'error',
+		})
+	} finally {
+		uni.hideLoading();
 	}
-}
-</script>
-
-<style lang="scss" scoped>
-.u-wrap {
-	height: calc(100vh);
-	/* #ifdef H5 */
-	height: calc(100vh - var(--window-top));
-	/* #endif */
-	display: flex;
-	flex-direction: column;
-}
-
-.u-search-box {
-	padding: 18rpx 30rpx;
-}
-
-.u-menu-wrap {
-	flex: 1;
-	display: flex;
-	overflow: hidden;
-}
-
-.u-search-inner {
-	background-color: rgb(234, 234, 234);
-	border-radius: 100rpx;
-	display: flex;
-	align-items: center;
-	padding: 10rpx 16rpx;
-}
-
-.u-search-text {
-	font-size: 26rpx;
-	color: $u-tips-color;
-	margin-left: 10rpx;
-}
-
-.u-tab-view {
-	width: 200rpx;
-	height: 100%;
-}
-
-.u-tab-item {
-	height: 110rpx;
-	background: #f6f6f6;
-	box-sizing: border-box;
-	display: flex;
-	align-items: center;
-	justify-content: center;
-	font-size: 26rpx;
-	color: #444;
-	font-weight: 400;
-	line-height: 1;
-}
-
-.u-tab-item-active {
-	position: relative;
-	color: #000;
-	font-size: 30rpx;
-	font-weight: 600;
-	background: #fff;
-}
-
-.u-tab-item-active::before {
-	content: "";
-	position: absolute;
-	border-left: 4px solid $u-primary;
-	height: 32rpx;
-	left: 0;
-	top: 39rpx;
-}
-
-.u-tab-view {
-	height: 100%;
-}
-
-.right-box {
-	background-color: rgb(250, 250, 250);
 }
 
-.page-view {
-	padding: 16rpx;
-}
+/**
+ * 1: 查看
+ * 2:沟通
+ * 3:上传照片
+ */
+function btnClick(row,type) {
+	console.log('btnClick', type, row);
+	if (type === 1) {
+		uni.navigateTo({
+			url: `/pages/order/order?orderId=${row.orderId}`
+		});
+	}
 
-.class-item {
-	margin-bottom: 30rpx;
-	background-color: #fff;
-	padding: 16rpx;
-	border-radius: 8rpx;
 }
+provide('onClick', btnClick);
 
-.class-item:last-child {
-	min-height: 100vh;
-}
 
-.item-title {
-	font-size: 26rpx;
-	color: $u-main-color;
-	font-weight: bold;
+function onChange(tabItem) {
+	tab.value = tabItem;
+	getList();
+	console.log('change', tabItem, tab.value);
 }
 
-.item-menu-name {
-	font-weight: normal;
-	font-size: 24rpx;
-	color: $u-main-color;
-}
 
-.item-container {
-	display: flex;
-	flex-wrap: wrap;
+async function init(){
+	getList();
 }
 
-.thumb-box {
-	width: 33.333333%;
-	display: flex;
-	align-items: center;
-	justify-content: center;
-	flex-direction: column;
-	margin-top: 20rpx;
-}
+onMounted(init)
+</script>
 
-.item-menu-image {
-	width: 120rpx;
-	height: 120rpx;
+<style lang="scss" scoped>
+.classify-main {
+	height: 100vh;
+
+	.list {
+		position: fixed;
+		top: 50px;
+		bottom: 0px;
+		left: 0px;
+		right: 0px;
+	}
 }
-</style>
+</style>

+ 52 - 0
pages/order/list/index.vue

@@ -0,0 +1,52 @@
+<template>
+    <view class="list-page">
+        <up-list @scrolltolower="scrolltolower" style="height: 100%;">
+            <up-list-item v-for="(item, index) in data" :key="index" >
+                <ListItem :data="item"/>
+            </up-list-item>
+            <up-loadmore
+					:line="true"
+					status="nomore"
+				></up-loadmore>
+        </up-list>
+      
+    </view>
+</template>
+
+<script setup>
+import { ref, reactive } from 'vue';
+import { onLoad, onShow } from '@dcloudio/uni-app';
+import ListItem from './listItem.vue';
+
+const props = defineProps({
+    data: {
+        type: Array,
+        default: [],
+    },
+});
+
+const emit = defineEmits(['refresh']);
+
+
+const scrolltolower = () => {
+    console.log('底部');
+    // emit('refresh');
+};
+
+</script>
+
+<style lang="scss" scoped>
+.list-page {
+
+    background: rgba(245, 245, 245, 1);
+    padding: 12px;
+    height: 100%;
+    overflow-y: auto;
+    .item {
+        height: 120px;
+        border-radius: 10px;
+        background: rgba(255, 255, 255, 1);
+        padding: 12px;
+    }
+}
+</style>

+ 206 - 0
pages/order/list/listItem.vue

@@ -0,0 +1,206 @@
+<template>
+    <view class="item">
+        <view class="item-img">
+            <img src="/static/img/dd.png" alt="" />
+        </view>
+        <view class="item-info">
+            <view class="item-title-box">
+                <view class="item-title">
+                    <view class="item-name">
+                        <!-- <dict-tag :options="lrr_service_category" :value="data.serviceCategory" /> -->
+                         姓名: {{  }}
+                        <view v-if="data.serviceType">
+                            -
+                            <dict-tag :options="lrr_study" :value="data.serviceType" v-if="data.serviceCategory === 2" />
+                            <dict-tag :options="lrr_chitchat" :value="data.serviceType" v-if="data.serviceCategory === 1" />
+                        </view>
+                        
+                    </view>
+                    <dict-tag :options="order_status" :value="data.orderStatus" />
+                </view>
+                <view class="item-de">
+                    服务地址:{{ data.address }}
+                </view>
+            </view>
+            <view class="item-box">
+                <view class="item-price"><span class="item-price-yuan">¥</span> {{ data.serviceOnePrice || 0 }}</view>
+                <view class="item-btns">
+                    <up-button type="error" text="查看" size="mini" :custom-style="btn_style"
+                        @click="onClick(1)"></up-button>
+                    <!-- <up-button type="error" text="沟通" size="mini" :custom-style="btn_style" @click="onClick(2)"></up-button>
+                        <up-button type="error" text="上传照片" size="mini" :custom-style="btn_style" @click="onClick(3)"></up-button> -->
+                </view>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script setup>
+import { inject } from 'vue';
+import DictTag from '@/components/DictTag/index.vue'
+import { computed } from 'vue';
+
+const props = defineProps({
+    data: {
+        type: Object,
+        default: () => {
+            return {}
+        }
+    }
+});
+
+const inject_click = inject('onClick');
+
+const lrr_service_category = inject('lrr_service_category');
+const lrr_chitchat = inject('lrr_chitchat');
+const lrr_study = inject('lrr_study');
+const order_status = inject('order_status');
+
+
+const status_map = {
+    1: '待服务',
+    2: '已取消',
+    3: '进行中',
+    4: '已完成',
+    5: '申请退款中',
+    6: '已退款',
+    7: '部分退款',
+    8: '待确认'
+}
+const status_color_map = {
+    1: '#3c9cff',
+    2: '#f56c6c',
+    3: '#3c9cff',
+    4: 'rgba(56, 148, 254, 1)',
+    5: 'orange',
+    6: '#3c9cff',
+    7: 'orange',
+    8: '#3c9cff'
+}
+
+const statysColor = computed(() => {
+    return {
+        color: status_color_map[props.data.orderStatus]
+    }
+});
+
+
+
+const btn_style = ` width: 120rpx; height: 50rpx; font-size: 24rpx;border-radius: 25rpx;margin-left: 12rpx;`;
+
+/**
+ * 1: 查看
+ * 2:沟通
+ * 3:上传照片
+ */
+function onClick() {
+    inject_click(props.data, 1);
+}
+</script>
+
+<style lang="scss" scoped>
+.item {
+    height: 120px;
+    border-radius: 10px;
+    background: rgba(255, 255, 255, 1);
+    padding: 12px;
+    margin-bottom: 12px;
+    display: flex;
+
+    .item-img {
+        width: 96px;
+        height: 96px;
+        margin-right: 12px;
+
+        image {
+            height: 100%;
+            width: 100%;
+        }
+    }
+
+    .item-info {
+        flex: 1;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-between;
+
+        .item-title-box {
+            .item-title {
+                font-size: 14px;
+                font-weight: 700;
+                letter-spacing: 0px;
+                line-height: 20.27px;
+                color: rgba(51, 51, 51, 1);
+                text-align: left;
+                vertical-align: top;
+                margin-bottom: 10px;
+
+                display: flex;
+                align-content: center;
+                justify-content: space-between;
+
+                .item-name {
+                    flex: 1;
+                    display: flex;
+                    // display: -webkit-box;
+                    // -webkit-box-orient: vertical;
+                    // -webkit-line-clamp: 1;
+                    // overflow: hidden;
+                    // text-overflow: ellipsis;
+                    // word-break: break-all;
+                }
+
+                .item-tag {
+                //    color: #3c9cff;
+                }
+
+            }
+
+            .item-de {
+                font-size: 12px;
+                font-weight: 500;
+                letter-spacing: 0px;
+                line-height: 17.38px;
+                color: rgba(153, 153, 153, 1);
+                text-align: left;
+                vertical-align: top;
+
+                display: -webkit-box;
+                -webkit-box-orient: vertical;
+                -webkit-line-clamp: 2;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                word-break: break-all;
+            }
+        }
+
+        .item-box {
+            display: flex;
+            align-content: flex-end;
+            justify-content: space-between;
+
+            .item-price {
+                font-size: 18px;
+                font-weight: 500;
+                letter-spacing: 0px;
+                line-height: 21.09px;
+                color: rgba(246, 74, 31, 1);
+                text-align: center;
+                vertical-align: top;
+
+                .item-price-yuan {
+                    font-size: 13px;
+                    font-weight: 700;
+                    letter-spacing: 0px;
+                    line-height: 21.09px;
+                    color: rgba(246, 74, 31, 1);
+                }
+            }
+
+            .item-btns {
+                display: flex;
+            }
+        }
+    }
+}
+</style>

+ 193 - 0
pages/order/order.vue

@@ -0,0 +1,193 @@
+<!-- 订单详情 -->
+<template>
+	<view class="order-detail">
+		<view class="user-info order-card">
+			<view class="font-title">基本信息</view>
+			<view class="user-box">
+				<img src="/static/img/dd.png" alt="" class="user-img" />
+				<view class="info-list">
+					<view>姓名:</view>
+					<view>被服务对象:</view>
+					<view>电话号码:</view>
+				</view>
+			</view>
+		</view>
+		<view class="service-info order-card">
+			<view class="font-title ">服务信息</view>
+			<view class="info-list">
+				<view>服务地址:</view>
+				<view>服务类别:</view>
+				<view>服务科目:</view>
+				<view>备注:</view>
+			</view>
+		</view>
+		<view class="register-info order-card">
+			<view class="font-title ">志愿者信息</view>
+			<view class="register-box">
+				<img src="/static/img/dd.png" alt="" class="register-img" />
+				<view class="info-list">
+					<view>时间:2025.4.1 15:00-18:0</view>
+					<view>姓名:</view>
+					<view>服务地址:</view>
+					<view>金额:<span class="price"><span class="price-yuan">¥</span> 200</span>
+					</view>
+				</view>
+			</view>
+
+		</view>
+
+		<view class="service-info order-card">
+			<view class="font-title">图片上传</view>
+			<up-upload :fileList="fileList" @afterRead="afterRead" @delete="deletePic" name="1" multiple
+				:maxCount="10"></up-upload>
+		</view>
+
+		<view class=" footer-g">
+			<up-button type="primary" text="前往沟通"></up-button>
+		</view>
+	</view>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+import { getToken } from '@/utils/auth'
+import config from '@/config'
+const baseUrl = config.baseUrl
+
+const fileList = ref([]);
+
+// 删除图片
+const deletePic = (event) => {
+	fileList.value.splice(event.index, 1);
+};
+
+// 新增图片
+const afterRead = async (event) => {
+	// 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式
+	let lists = [].concat(event.file);
+	let fileListLen = fileList.value.length;
+	lists.map((item) => {
+		fileList.value.push({
+			...item,
+			status: 'uploading',
+			message: '上传中',
+		});
+	});
+	for (let i = 0; i < lists.length; i++) {
+		const result = await uploadFilePromise(lists[i]);
+		let item = fileList.value[fileListLen];
+		fileList.value.splice(fileListLen, 1, {
+			...item,
+			status: 'success',
+			message: '',
+			url: result.url,
+		});
+		fileListLen++;
+	}
+};
+
+const uploadFilePromise = (data) => {
+	console.log('data',data);
+	
+	return new Promise((resolve, reject) => {
+		wx.uploadFile({
+			url: baseUrl + '/common/upload', // 仅为示例,非真实的接口地址
+			filePath: data.url,
+			name: 'file',
+			formData: {
+				file: data,
+			},
+			header: {
+				'Authorization': 'Bearer ' + getToken(),   // 自定义请求头
+			},
+			success: (res) => {
+				const data = JSON.parse(res.data);
+				resolve(data);
+			},
+			fail: (err) => {
+				uni.showToast({
+					title: '上传失败',
+					icon: 'none'
+				})
+				console.error(' 转换失败:', err);
+				reject();
+			}
+		});
+	});
+};
+</script>
+<style lang="scss" scoped>
+.order-detail {
+	position: fixed;
+	top: 0;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	padding: 12px 12px 24px;
+	background: rgba(245, 245, 245, 1);
+
+
+	.order-card {
+		border-radius: 8px;
+		background: rgba(255, 255, 255, 1);
+		padding: 12px;
+		margin-bottom: 12px;
+	}
+
+	.font-title {
+		margin-bottom: 12px;
+	}
+
+	.user-box {
+		display: flex;
+
+		.user-img {
+			width: 65.8px;
+			height: 65.8px;
+			margin-right: 12px;
+		}
+
+	}
+
+	.register-box {
+		display: flex;
+		margin-bottom: 12px;
+
+		.register-img {
+			width: 90px;
+			height: 90px;
+			margin-right: 12px;
+		}
+
+	}
+
+	.info-list {
+		flex: 1;
+		font-size: 14px;
+		font-weight: 500;
+		letter-spacing: 0px;
+		line-height: 23.27px;
+		color: rgba(51, 51, 51, 1);
+	}
+
+	.price {
+		font-size: 18px;
+		font-weight: 500;
+		color: rgba(246, 74, 31, 1);
+
+		.price-yuan {
+			font-size: 13px;
+			font-weight: 700;
+			color: rgba(246, 74, 31, 1);
+		}
+	}
+
+	.footer-g {
+		padding: 12px;
+		position: absolute;
+		bottom: 18px;
+		left: 0px;
+		right: 0px;
+	}
+}
+</style>

+ 215 - 0
pages/register/data.js

@@ -0,0 +1,215 @@
+const sex_option = [
+    {
+        name: '男',
+    },
+    {
+        name: '女',
+    },
+]
+
+const city_option = [
+    {
+        name: '重庆',
+    },
+    {
+        name: '四川',
+    },
+]
+
+const rules = {
+    name: [
+        {
+            type: 'string',
+            required: true,
+            message: '请填写姓名',
+            trigger: ['blur', 'change']
+        },
+        {
+            // 此为同步验证,可以直接返回true或者false,如果是异步验证,稍微不同,见下方说明
+            validator: (rule, value, callback) => {
+                // 调用uview-plus自带的js验证规则,详见:https://uview-plus.jiangruyi.com/js/test.html
+                return uni.$u.test.chinese(value);
+            },
+            message: "姓名必须为中文",
+            // 触发器可以同时用blur和change,二者之间用英文逗号隔开
+            trigger: ["change", "blur"],
+        },
+    ],
+    sex: [
+        {
+            type: 'string',
+            max: 1,
+            required: true,
+            message: '请选择男或女',
+            trigger: ['blur', 'change']
+        }
+    ],
+    age: [],
+    idCard: [],
+    city: [],
+    address: []
+}
+
+//陪伴陪聊注册 1
+const chatting = [
+    {
+        label: "姓名",
+        key: "name",
+        type: "input",
+        rules: rules.name,
+        required:true
+    },
+    {
+        label: "性别",
+        key: "sex",
+        type: "select",
+        option: sex_option,
+        rules: rules.sex,
+        required:true
+    },
+    {
+        label: "年龄",
+        key: "age",
+        type: "input",
+        rules: rules.age,
+    },
+    {
+        label: "手机号",
+        key: "phonenumber",
+        type: "phone-code",
+    },
+    // {
+    //     label: "服务类型",
+    //     key: "",
+    //     type: "select",
+    //     option: city_option,
+    //     rules: rules.city
+    // },
+    {
+        label: "地区",
+        key: "city",
+        type: "select",
+        option: city_option,
+        rules: rules.city,
+    },
+    {
+        label: "详细地址",
+        key: "address",
+        type: "input",
+        rules: rules.address
+    },
+    {
+        label: "技能简介",
+        key: "skillDescribe",
+        type: "textarea",
+    },
+]
+
+//家庭辅导(教育)2
+const education = [
+    {
+        label: "姓名",
+        key: "name",
+        type: "input",
+        rules: rules.name,
+        required:true
+    },
+    {
+        label: "性别",
+        key: "sex",
+        type: "select",
+        option: sex_option,
+        rules: rules.sex,
+        required:true
+    },
+    {
+        label: "年龄",
+        key: "age",
+        type: "input",
+        rules: rules.age
+    },
+    {
+        label: "手机号",
+        key: "phonenumber",
+        type: "phone-code",
+    },
+    {
+        label: "证件号",
+        key: "idCard",
+        type: "input",
+    },
+    {
+        label: "地区",
+        key: "city",
+        type: "select",
+        option: city_option,
+        rules: rules.city
+
+    },
+    {
+        label: "地址",
+        key: "address",
+        type: "input",
+        rules: rules.address
+    },
+    {
+        label: "技能简介",
+        key: "skillDescribe",
+        type: "textarea",
+    },
+]
+//家庭清洁5
+const clean = [
+    {
+        label: "姓名",
+        key: "name",
+        type: "input",
+        rules: rules.name
+    },
+    {
+        label: "性别",
+        key: "sex",
+        type: "select",
+        option: sex_option,
+        rules: rules.sex
+    },
+    {
+        label: "年龄",
+        key: "age",
+        type: "input",
+        rules: rules.age
+    },
+    {
+        label: "手机号",
+        key: "phonenumber",
+        type: "phone-code",
+    },
+    {
+        label: "证件号",
+        key: "idCard",
+        type: "input",
+    },
+    {
+        label: "地区",
+        key: "city",
+        type: "select",
+        option: city_option,
+        rules: rules.city
+
+    },
+    {
+        label: "地址",
+        key: "address",
+        type: "input",
+        rules: rules.address
+    },
+    {
+        label: "技能简介",
+        key: "skillDescribe",
+        type: "textarea",
+    },
+]
+
+
+
+export { chatting,     education, clean }

+ 191 - 0
pages/register/register.vue

@@ -0,0 +1,191 @@
+<template>
+	<view class="register-main">
+		<view class="register-user-info">
+			<FontTitle title="请完成注册信息填报" />
+			<CustForm :column="com_column" ref="cust_form_ref" />
+		</view>
+		<view class="updata-imgs">
+			
+		</view>
+		<!-- <UpdataImgs :data="updata_list[0]" ref="userImg" v-if="updata_list[0].permission.includes(data.key)" />
+		<UpdataImgs :data="updata_list[1]" ref="zsImg" v-if="updata_list[1].permission.includes(data.key)" /> -->
+
+		<view v-for="item in updata_list" :key="item.key" class="updata-imgs">
+			<UpdataImgs :data="item" ref="zsImg" v-if="item.permission.includes(data.key)" @onSubmit="onChange"/>
+		</view>
+
+		<up-button type="primary" text="确定" @click="onSubmit"></up-button>
+
+	</view>
+</template>
+
+<script setup>
+import { ref, reactive } from 'vue';
+import { onLoad } from '@dcloudio/uni-app';
+import FontTitle from "../../components/font-title/index.vue";
+import CustForm from "../../components/cust-form/index";
+import UpdataImgs from "../../components/updata-imgs/index.vue";
+import { chatting, education, clean } from "./data";
+import { add } from "../../api/volunteer";
+import { computed } from 'vue';
+
+
+const userImg = ref(null);
+const zsImg = ref(null);
+
+
+const updata_list = [
+	{
+		title: '上传头像',
+		text: '上传您的头像',
+		img: '/static/img/updata-user-img.png',
+		key: 'volunteerPicture',
+		ref: userImg,
+		permission: [1, 2],
+		required: true
+	},
+	{
+		title: '个人身份证',
+		text: '上传您的个人身份证',
+		img: '/static/img/updata-user-img.png',
+		key: 'idCardPicture',
+		ref: zsImg,
+		permission: [1, 2],
+		required: true
+	},
+	{
+		title: '职业、资质证书',
+		text: '上传您的职业、资质证书',
+		img: '/static/img/updata-user-img.png',
+		key: 'certificationPicture',
+		ref: zsImg,
+		permission: [1],
+		required: false
+	}
+]
+
+const cust_form_ref = ref(null);
+
+const data = ref(null);
+
+const file_url=reactive({});
+
+
+const sex_status = {
+	'男': 0,
+	'女': 1
+}
+const register_column = {
+	1: chatting,
+	2: education,
+	5: clean
+}
+
+//根据类型获取表单item 值
+const com_column = computed(() => {
+	return data.value ? register_column[data.value.key] : []
+})
+
+function onSubmit() {
+	try {
+		// 校验表单并获取数据
+		// const res = await ;
+		cust_form_ref.value.onSubmit().then(async (res) => {
+			console.log('===res===>', res,file_url);
+
+			//文件必传校验
+			for (let i = 0; i < updata_list.length; i++) {
+				const element = updata_list[i];
+				console.log(element.required , element.permission.includes(data.value.key) , file_url[element.key]);
+				
+				
+				const type = element.required && element.permission.includes(data.value.key) && !file_url[element.key];
+				console.log('element',element,type);
+
+				if (type) {
+					uni.showToast({
+						title: '请上传' + element.title,
+						icon: 'error'
+					})
+					return;
+				}
+			}
+
+			const parmas = {
+				serviceCategory: data.value.key,
+				...file_url
+			};
+			for (const key in res) {
+				parmas[key] = key == 'sex' ? sex_status[res[key]] : res[key];
+			}
+
+			console.log('提交',parmas);
+
+			// return;
+			// 提交接口,注册人员
+			const submit_res = await add(parmas);
+			if(submit_res.code == 200){
+				uni.showToast({
+					title: '注册成功',
+					icon: 'none'
+				})
+				uni.navigateBack();
+				return;
+			}
+			uni.showToast({
+				title: res.msg,
+				icon: 'none'
+			})
+			console.log('==submit_res====>', submit_res);
+		})
+
+
+	} catch (error) {
+		console.log('error', error);
+
+	} finally {
+
+	}
+
+}
+
+function onChange({key,url}) {
+	console.log('onChange', key,url);
+	Object.assign(file_url,{
+		[key]:url
+	})
+}
+
+
+onLoad((options) => {
+	const option = JSON.parse(decodeURIComponent(options.data));
+	data.value = option;
+	console.log("option", option);
+
+	uni.setNavigationBarTitle({
+		title: option.name  // 根据业务逻辑调整 
+	});
+})
+
+
+</script>
+
+<style lang="scss" scoped>
+.register-main {
+	padding: 12px;
+	background-color: rgba(245, 245, 245, 1);
+
+	// height: 100vh;
+	.register-user-info {
+		margin-bottom: 12px;
+		background-color: #fff;
+		border-radius: 8px;
+		padding: 18px 16px;
+	}
+
+	.updata-imgs {
+		margin-bottom: 12px;
+
+	}
+}
+</style>

+ 65 - 0
pnpm-lock.yaml

@@ -0,0 +1,65 @@
+lockfileVersion: '9.0'
+
+settings:
+  autoInstallPeers: true
+  excludeLinksFromLockfile: false
+
+importers:
+
+  .:
+    dependencies:
+      dayjs:
+        specifier: ^1.11.13
+        version: 1.11.13
+      uview-plus:
+        specifier: ^3.4.9
+        version: 3.4.13
+
+packages:
+
+  clipboard@2.0.11:
+    resolution: {integrity: sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==}
+
+  dayjs@1.11.13:
+    resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==}
+
+  delegate@3.2.0:
+    resolution: {integrity: sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==}
+
+  good-listener@1.2.2:
+    resolution: {integrity: sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==}
+
+  select@1.1.2:
+    resolution: {integrity: sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==}
+
+  tiny-emitter@2.1.0:
+    resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==}
+
+  uview-plus@3.4.13:
+    resolution: {integrity: sha512-83aSlZdq3POXMSYUV/XqAZPEWnPrvi1/GuUdsQXRtYrrVq2Zu1OgmxOJoGn7LWYi3kGDXnYVjT0Un5WCXgq4cQ==}
+    engines: {HBuilderX: ^3.1.0}
+
+snapshots:
+
+  clipboard@2.0.11:
+    dependencies:
+      good-listener: 1.2.2
+      select: 1.1.2
+      tiny-emitter: 2.1.0
+
+  dayjs@1.11.13: {}
+
+  delegate@3.2.0: {}
+
+  good-listener@1.2.2:
+    dependencies:
+      delegate: 3.2.0
+
+  select@1.1.2: {}
+
+  tiny-emitter@2.1.0: {}
+
+  uview-plus@3.4.13:
+    dependencies:
+      clipboard: 2.0.11
+      dayjs: 1.11.13

BIN
static/empty/数据为空.png


BIN
static/empty/无历史记录.png


BIN
static/empty/无收藏.png


BIN
static/empty/无新闻列表.png


BIN
static/empty/无权限.png


BIN
static/empty/暂无搜索结果.png


BIN
static/empty/暂无评论.png


BIN
static/empty/没有wifi.png


BIN
static/empty/没有优惠券.png


BIN
static/empty/没有收货地址.png


BIN
static/empty/消息为空.png


BIN
static/empty/消息列表为空.png


BIN
static/empty/订单为空.png


BIN
static/empty/购物车为空.png


BIN
static/empty/页面不存在.png


BIN
static/img/dd.png


BIN
static/img/updata-user-img.png


+ 29 - 0
static/scss/global.scss

@@ -88,3 +88,32 @@
       }
     }
   }
+
+
+.font-title {
+  font-size: 16px;
+  font-weight: 700;
+  line-height: 23.17px;
+  color: rgba(0, 0, 0, 1);
+}
+
+.font-text {
+  font-size: 12px;
+  font-weight: 700;
+  line-height: 17.38px;
+  color: rgba(153, 153, 153, 1);
+}
+.empty-null {
+  display: flex;
+  margin-top: 25%;
+  justify-content: center;
+  height: 100%;
+  width: 100%;
+}
+.empty-null  image  {
+  width: 200px;
+  height: 200px;
+}
+.u-form-item__body__left {
+  padding-left: 8px;
+}

+ 25 - 0
utils/dict.js

@@ -0,0 +1,25 @@
+import { getDicts } from '@/api/system/dict.js';
+import {ref,toRefs} from 'vue'
+function setDict(_key, value) {
+    const dict = [];
+    if (_key !== null && _key !== "") {
+      dict.push({
+        key: _key,
+        value: value
+      });
+    }
+    return dict;
+  }
+export function useDict(...args) {
+    const res = ref({});
+    return (() => {
+      args.forEach((dictType, index) => {
+        res.value[dictType] = [];
+        getDicts(dictType).then(resp => {
+            res.value[dictType] = resp.data.map(p => ({ label: p.dictLabel, value: p.dictValue, elTagType: p.listClass, elTagClass: p.cssClass }))
+            setDict(dictType, res.value[dictType]);
+         })
+      })
+      return toRefs(res.value);
+    })()
+  }