浏览代码

Merge branch 'master' of http://47.100.37.243:10191/wutt/manHourHousekeeper

zhouyy 6 月之前
父节点
当前提交
b2fb51f126
共有 100 个文件被更改,包括 17205 次插入256 次删除
  1. 1 0
      fhKeeper/formulahousekeeper/ArticleOperation/src/main/java/com/my/bigevent/pojo/Article.java
  2. 1 1
      fhKeeper/formulahousekeeper/articleBackend/index.html
  3. 2 3
      fhKeeper/formulahousekeeper/articleBackend/src/components/backend/TinymceEditor.vue
  4. 122 118
      fhKeeper/formulahousekeeper/articleBackend/src/views/article/ArticleManage.vue
  5. 0 1
      fhKeeper/formulahousekeeper/customerBuler-crm/index.html
  6. 7 7
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/analysis/index.vue
  7. 4 4
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/corpreport/index.vue
  8. 57 22
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/header/header.vue
  9. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/login.vue
  10. 2 1
      fhKeeper/formulahousekeeper/customerBuler-crm/vite.config.ts
  11. 14 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/config/MyExitCodeGenerator.java
  12. 15 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/DepartmentVO.java
  13. 6 6
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ContractServiceImpl.java
  14. 43 11
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DepartmentServiceImpl.java
  15. 70 79
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  16. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java
  17. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ContractMapper.xml
  18. 2 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/.env.development
  19. 3 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/.env.production
  20. 22 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/.gitignore
  21. 49 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/README.bak.md
  22. 140 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/README.md
  23. 24 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/babel.config.js
  24. 1 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/build.bat
  25. 13281 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/package-lock.json
  26. 65 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/package.json
  27. 2 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/public/axios.min.js
  28. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/public/favicon.ico
  29. 87 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/public/index.html
  30. 186 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/App.vue
  31. 33 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/app.js
  32. 75 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/collapse.js
  33. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/icon/kefu.png
  34. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/1.jpg
  35. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/jz1.jpg
  36. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/jz2.jpg
  37. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/jz3.jpg
  38. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/jz4.jpg
  39. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/r1.jpg
  40. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/r2.jpg
  41. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/r3.jpg
  42. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/r4.jpg
  43. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/r5.jpg
  44. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/alt.jpg
  45. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/chong.png
  46. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/cover/1.jpg
  47. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/cover/2.jpg
  48. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/cover/3.jpg
  49. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/cover/4.jpg
  50. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/cover/5.jpg
  51. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/group/hb1.jpg
  52. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/group/hb2.jpg
  53. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/group/tx1.jpg
  54. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/group/tx2.jpg
  55. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/group/tx3.jpg
  56. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/group/tx4.jpg
  57. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/home/banner_1.png
  58. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/home/banner_2.png
  59. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/home/banner_3.png
  60. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/home/check.png
  61. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/home/edit.png
  62. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/home/more.png
  63. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/home/my.png
  64. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/home/wait.png
  65. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/index/banner4.jpeg
  66. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/index/banner_1.png
  67. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/index/banner_2.png
  68. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/index/banner_3.png
  69. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/kf.jpg
  70. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/login_logo.png
  71. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/logo.png
  72. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/not.jpeg
  73. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/null.png
  74. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/orderList1.jpg
  75. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/orderList2.jpg
  76. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/beij.png
  77. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/cl.png
  78. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/dt.png
  79. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/hb.png
  80. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/head_back.jpg
  81. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/p.png
  82. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/qb.png
  83. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/tg.png
  84. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/tx.jpg
  85. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/userHead.png
  86. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/yhk.png
  87. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/poster/1.jpg
  88. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/poster/2.jpg
  89. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/poster/3.jpg
  90. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/poster/4.jpg
  91. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/qwcode.png
  92. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/qx.png
  93. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/qxbj.png
  94. 1 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/shju.json
  95. 363 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/style/common.less
  96. 539 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/style/font/demo.css
  97. 1706 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/style/font/demo_index.html
  98. 279 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/style/font/iconfont.css
  99. 二进制
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/style/font/iconfont.eot
  100. 0 0
      fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/style/font/iconfont.js

+ 1 - 0
fhKeeper/formulahousekeeper/ArticleOperation/src/main/java/com/my/bigevent/pojo/Article.java

@@ -37,6 +37,7 @@ public class Article {
     private String categoryNames;
 
     private String coverImgUrl;
+    private Integer viewCount;
 
     @JsonFormat(pattern = "yyyy-MM-dd")
     @DateTimeFormat(pattern = "yyyy-MM-dd")

+ 1 - 1
fhKeeper/formulahousekeeper/articleBackend/index.html

@@ -4,7 +4,7 @@
     <meta charset="UTF-8">
     <link rel="icon" href="/favicon.ico">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>Vite App</title>
+    <title>珊瑚岛-文章管理后台</title>
   </head>
   <body>
     <div id="app"></div>

+ 2 - 3
fhKeeper/formulahousekeeper/articleBackend/src/components/backend/TinymceEditor.vue

@@ -49,7 +49,7 @@ import 'tinymce/plugins/lists'; //列表插件
 import 'tinymce/plugins/media'; //插入编辑媒体
 import 'tinymce/plugins/nonbreaking'; //插入不间断空格
 import 'tinymce/plugins/pagebreak'; //插入分页符
-import 'tinymce/plugins/preview'; //
+import 'tinymce/plugins/preview'; //
 import 'tinymce/plugins/quickbars'; //快速工具栏
 import 'tinymce/plugins/save'; //保存
 import 'tinymce/plugins/searchreplace'; //查找替换
@@ -81,7 +81,7 @@ const emit = defineEmits(['input']);
 const piniaToken = JSON.parse(localStorage.getItem('pinia-token') || '')
 const myTinyInit = reactive({
   width: '100%',
-  height: 500,
+  height: 800,
   branding: true,
   menubar: true,
   resize: true,
@@ -100,7 +100,6 @@ const myTinyInit = reactive({
   //图片上传方法(注意!!:要使用 promise 对象中的 resolve 返回图片路径,否则会报错)
   images_upload_handler: (blobInfo) => new Promise((resolve, reject) => {
       let formData = new FormData();
-      console.log(blobInfo, '<==== blobInfo')
       formData.append('multipartFile', blobInfo.blob(), blobInfo.filename());
       axios.post(`/api/common/uploadFile`, formData, {
           headers: ({

+ 122 - 118
fhKeeper/formulahousekeeper/articleBackend/src/views/article/ArticleManage.vue

@@ -19,20 +19,20 @@ import { ref } from 'vue'
 const categorys = ref([])
 
 //用户搜索时选中的分类id
-const categoryId=ref('')
+const categoryId = ref('')
 
 //用户搜索时选中的发布状态
-const state=ref('')
+const state = ref('')
 
 //文章列表数据模型
 const articles = ref([])
 
 const productList = ref([
-    { id: '1', label: '工时管家' }, 
-    { id: '2', label: '随访管家' }, 
-    { id: '3', label: '项目管家' }, 
-    { id: '4', label: '客户管家' }, 
-    { id: '5', label: '生产车间管家' }, 
+    { id: '1', label: '工时管家' },
+    { id: '2', label: '随访管家' },
+    { id: '3', label: '项目管家' },
+    { id: '4', label: '客户管家' },
+    { id: '5', label: '生产车间管家' },
 ])
 const quilleditorKey = ref(1)
 
@@ -52,32 +52,32 @@ const onCurrentChange = (num) => {
     articleList();
 }
 //回显文章标签
-import {articleCategoryListService, articleListService,articleAddService, articleDeleteService,uploadFileService} from '@/api/article.js'
-const articleCategoryList=async()=>{
+import { articleCategoryListService, articleListService, articleAddService, articleDeleteService, uploadFileService } from '@/api/article.js'
+const articleCategoryList = async () => {
     let result = await articleCategoryListService();
-    categorys.value=result.data;
+    categorys.value = result.data;
 }
 articleCategoryList();
 
 //获取文章列表数据
-const articleList=async()=>{
-    let params={
-        pageNum:pageNum.value,
-        pageSize:pageSize.value,
-        categoryId:categoryId.value?categoryId.value:null,
-        state:state.value?state.value:null
+const articleList = async () => {
+    let params = {
+        pageNum: pageNum.value,
+        pageSize: pageSize.value,
+        categoryId: categoryId.value ? categoryId.value : null,
+        state: state.value ? state.value : null
     }
-    let result =await articleListService(params);
+    let result = await articleListService(params);
     //渲染视图
-    total.value=result.data.total;
-    articles.value=result.data.items;
+    total.value = result.data.total;
+    articles.value = result.data.items;
 
     //处理数据,给数据模型扩展一个属性 categoryName ,分类名称
-    for(let i=0;i<articles.value.length;i++){
-        let article=articles.value[i];
-        for(let j=0;j<categorys.value.length;j++){
-            if(article.categoryId==categorys.value[j].id){
-                article.categoryName=categorys.value[j].categoryName
+    for (let i = 0; i < articles.value.length; i++) {
+        let article = articles.value[i];
+        for (let j = 0; j < categorys.value.length; j++) {
+            if (article.categoryId == categorys.value[j].id) {
+                article.categoryName = categorys.value[j].categoryName
             }
         }
     }
@@ -85,7 +85,7 @@ const articleList=async()=>{
 articleList()
 
 // 添加文章功能
-import {Plus} from '@element-plus/icons-vue'
+import { Plus } from '@element-plus/icons-vue'
 //控制抽屉是否显示
 const visibleDrawer = ref(false)
 //添加表单数据模型
@@ -93,53 +93,53 @@ const articleModel = ref({
     title: '',
     categoryId: '',
     coverImg: '',
-    content:'',
-    state:'',
+    content: '',
+    state: '',
     profile: '',
     productId: ''
 })
 const fileList = ref([])
 const options = ref({
-  theme: "snow",
-  bounds: document.body,
-  debug: "warn",
-  modules: {
-    // 工具栏配置
-    toolbar: [
-      ["bold", "italic", "underline", "strike"],      // 加粗 斜体 下划线 删除线
-      ["blockquote", "code-block"],                   // 引用  代码块
-      [{ list: "ordered" }, { list: "bullet" }],      // 有序、无序列表
-      [{ indent: "-1" }, { indent: "+1" }],           // 缩进
-      [{ size: ["small", false, "large", "huge"] }],  // 字体大小
-      [{ header: [1, 2, 3, 4, 5, 6, false] }],        // 标题
-      [{ color: [] }, { background: [] }],            // 字体颜色、字体背景颜色
-      [{ align: [] }],                                // 对齐方式
-      ["clean"],                                      // 清除文本格式
-      ["link", "image"]                      // 链接、图片、视频
-    ],
-    // ImageDrop: true,  // PS:因为QuillEditor自带可拖拽此配置可以不开,开启拖动会复制图片
-    // todo 富文本导入图片是否需要缩放拖拽 
-    // imageResize: {
-    //   displayStyles: {
-    //     backgroundColor: 'black',
-    //     border: 'none',
-    //     color: 'white',
-    //   },
-    //   modules: ['Resize', 'DisplaySize', 'Toolbar'],
-    // },
-  },
-  placeholder: "请输入内容",
-//   readOnly: props.readOnly
+    theme: "snow",
+    bounds: document.body,
+    debug: "warn",
+    modules: {
+        // 工具栏配置
+        toolbar: [
+            ["bold", "italic", "underline", "strike"],      // 加粗 斜体 下划线 删除线
+            ["blockquote", "code-block"],                   // 引用  代码块
+            [{ list: "ordered" }, { list: "bullet" }],      // 有序、无序列表
+            [{ indent: "-1" }, { indent: "+1" }],           // 缩进
+            [{ size: ["small", false, "large", "huge"] }],  // 字体大小
+            [{ header: [1, 2, 3, 4, 5, 6, false] }],        // 标题
+            [{ color: [] }, { background: [] }],            // 字体颜色、字体背景颜色
+            [{ align: [] }],                                // 对齐方式
+            ["clean"],                                      // 清除文本格式
+            ["link", "image"]                      // 链接、图片、视频
+        ],
+        // ImageDrop: true,  // PS:因为QuillEditor自带可拖拽此配置可以不开,开启拖动会复制图片
+        // todo 富文本导入图片是否需要缩放拖拽 
+        // imageResize: {
+        //   displayStyles: {
+        //     backgroundColor: 'black',
+        //     border: 'none',
+        //     color: 'white',
+        //   },
+        //   modules: ['Resize', 'DisplaySize', 'Toolbar'],
+        // },
+    },
+    placeholder: "请输入内容",
+    //   readOnly: props.readOnly
 });
 
 //导入token,方便编辑完文章后保存至服务器
-import {userTokenStore} from '@/stores/token.js'
-const tokenStore=userTokenStore();
+import { userTokenStore } from '@/stores/token.js'
+const tokenStore = userTokenStore();
 
 //上传成功的回调函数
-const uploadSuccess=(result)=>{
+const uploadSuccess = (result) => {
     //将服务器响应的图片地址赋值给 articleModel 的 coverImg
-    articleModel.value.coverImg=result.data;
+    articleModel.value.coverImg = result.data;
     console.log(result.data)
 }
 
@@ -148,39 +148,45 @@ const fileExceedsLimit = () => {
 }
 
 // 添加文章
-import {ElMessage, ElMessageBox} from 'element-plus'
-const addArticle=async(clickState)=>{
+import { ElMessage, ElMessageBox } from 'element-plus'
+const addArticle = async (clickState) => {
     // 把发布文章yes或草稿no赋值给数据模型
-    articleModel.value.state=clickState;
+    articleModel.value.state = clickState;
     const { content, title, profile, categoryId, productId } = articleModel.value
     let str = ''
-    if(!content) {
+    if (!content) {
         str += '文章内容不能为空,'
     }
-    if(!title) {
+    if (!title) {
         str += '文章标题不能为空,'
     }
-    if(!profile) {
+    if (!profile) {
         str += '文章封面不能为空,'
     }
-    if(!categoryId || categoryId.length <= 0) {
+    if (!categoryId || categoryId.length <= 0) {
         str += '文章标签不能为空,'
     }
-    if(fileList.value.length <= 0) {
+    if (fileList.value.length <= 0) {
         str += '文章封面不能为空,'
     }
-    if(!productId || productId == '0') {
+    if (!productId || productId == '0') {
         str += '文章所属产品不能为空,'
     }
-    if(str) {
+    if (str) {
         ElMessage.warning(str)
         return
     }
-    const formVla = { ...articleModel.value, categoryIds: (articleModel.value.categoryId || []).join(',') }
+    const formVla = {
+        ...articleModel.value, categoryIds: (articleModel.value.categoryId || []).join(','), content: content.replace(/<img\s+[^>]*src=["']([^"']+)["'][^>]*>/g, (match, src) => {
+            // 对 src 进行处理,只保留 "/upload/..." 部分
+            let newSrc = src.replace(/^(?:\.{2}\/)?(upload\/.*)/, '/\$1');
+            return match.replace(src, newSrc);
+        })
+    }
     delete formVla.categoryId
     const formData = new FormData()
     for (const key in formVla) {
-        if(key == 'coverImg') {
+        if (key == 'coverImg') {
             let file = fileList.value[0].raw
             // if(!isFile(file)) {
             //     file = base64ToFile(file, 'image.png')
@@ -192,8 +198,8 @@ const addArticle=async(clickState)=>{
     }
     //调用接口
     // let result=await articleAddService(articleModel.value)
-    let result=await articleAddService(formData)
-    ElMessage.success(result.msg?result.msg:"添加文章成功!")
+    let result = await articleAddService(formData)
+    ElMessage.success(result.msg ? result.msg : "添加文章成功!")
 
     //让添加文章的抽屉消失
     visibleDrawer.value = false;
@@ -218,17 +224,17 @@ const fileUploadArticle = async (row) => {
     }]
 }
 const base64ToFile = (base64String, fileName) => {
-  const arr = base64String.split(',');
-  const mime = arr[0].match(/:(.*?);/)[1];
-  const bstr = atob(arr[1]);
-  let n = bstr.length;
-  const u8arr = new Uint8Array(n);
-
-  while (n--) {
-    u8arr[n] = bstr.charCodeAt(n);
-  }
+    const arr = base64String.split(',');
+    const mime = arr[0].match(/:(.*?);/)[1];
+    const bstr = atob(arr[1]);
+    let n = bstr.length;
+    const u8arr = new Uint8Array(n);
+
+    while (n--) {
+        u8arr[n] = bstr.charCodeAt(n);
+    }
 
-  return new File([u8arr], fileName, { type: mime });
+    return new File([u8arr], fileName, { type: mime });
 }
 
 const addArticleAdministration = () => {
@@ -256,7 +262,7 @@ const editArticle = (row) => {
         coverImg: '',
         productId: productId
     }
-    if(coverImgUrl) {
+    if (coverImgUrl) {
         fileList.value = [{
             name: '图片',
             // url: `data:image/jpeg;base64, ${coverImg}`,
@@ -267,7 +273,7 @@ const editArticle = (row) => {
     } else {
         fileList.value = []
     }
-    
+
 
     visibleDrawer.value = true
 }
@@ -282,8 +288,8 @@ const deleteArticle = async (row) => {
             type: 'warning',
         }
     ).then(async () => {
-        let result=await articleDeleteService({ id })
-        ElMessage.success(result.message?result.message:"删除文章成功!")
+        let result = await articleDeleteService({ id })
+        ElMessage.success(result.message ? result.message : "删除文章成功!")
         articleList()
     })
 }
@@ -302,11 +308,7 @@ const deleteArticle = async (row) => {
         <el-form inline>
             <el-form-item label="文章标签:">
                 <el-select placeholder="请选择" v-model="categoryId">
-                    <el-option 
-                        v-for="c in categorys" 
-                        :key="c.id" 
-                        :label="c.categoryName"
-                        :value="c.id">
+                    <el-option v-for="c in categorys" :key="c.id" :label="c.categoryName" :value="c.id">
                     </el-option>
                 </el-select>
             </el-form-item>
@@ -319,7 +321,7 @@ const deleteArticle = async (row) => {
             </el-form-item>
             <el-form-item>
                 <el-button type="primary" @click="articleList">搜索</el-button>
-                <el-button @click="categoryId='';state=''">重置</el-button>
+                <el-button @click="categoryId = ''; state = ''">重置</el-button>
             </el-form-item>
         </el-form>
         <!-- 文章列表 -->
@@ -328,6 +330,7 @@ const deleteArticle = async (row) => {
             <el-table-column label="标签" prop="categoryNames"></el-table-column>
             <el-table-column label="发表时间" prop="createTime"> </el-table-column>
             <el-table-column label="状态" prop="state"></el-table-column>
+            <el-table-column label="浏览量" prop="viewCount"></el-table-column>
             <el-table-column label="操作" width="100">
                 <template #default="{ row }">
                     <el-button :icon="Edit" circle plain type="primary" @click="editArticle(row)"></el-button>
@@ -339,20 +342,20 @@ const deleteArticle = async (row) => {
             </template>
         </el-table>
         <!-- 分页条 -->
-        <el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[5, 10 ,20, 50, 100]"
+        <el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[5, 10, 20, 50, 100]"
             layout="jumper, total, sizes, prev, pager, next" background :total="total" @size-change="onSizeChange"
             @current-change="onCurrentChange" style="margin-top: 20px; justify-content: flex-end" />
 
-            <!-- 抽屉 -->
-        <el-drawer v-model="visibleDrawer" :title="`${articleModel.id ? '编辑文章' : '添加文章'}`" direction="rtl" size="50%">
+        <!-- 抽屉 -->
+        <el-drawer v-model="visibleDrawer" :title="`${articleModel.id ? '编辑文章' : '添加文章'}`" direction="rtl" size="100%">
             <!-- 添加文章表单 -->
-            <el-form :model="articleModel" label-width="100px" >
-                <el-form-item label="文章标题" >
+            <el-form :model="articleModel" label-width="100px">
+                <el-form-item label="文章标题">
                     <el-input v-model="articleModel.title" placeholder="请输入标题" :maxlength="100"></el-input>
                 </el-form-item>
-                <el-form-item label="文章简介" >
-                    <el-input type="textarea"
-                    :autosize="{ minRows: 2, maxRows: 4}" v-model="articleModel.profile" placeholder="请输入简介" :maxlength="250"></el-input>
+                <el-form-item label="文章简介">
+                    <el-input type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" v-model="articleModel.profile"
+                        placeholder="请输入简介" :maxlength="250"></el-input>
                 </el-form-item>
                 <el-form-item label="文章标签">
                     <el-select placeholder="请选择" multiple v-model="articleModel.categoryId" style="width: 100%;">
@@ -374,15 +377,11 @@ const deleteArticle = async (row) => {
                             headers: 设置上传的请求头
                             on-success: 上传成功的回调函数
                     -->
-                    <el-upload
-                        v-model:file-list="fileList"
-                        list-type="picture-card"
-                        :auto-upload="true"
-                        :limit="1"
-                        :on-exceed="fileExceedsLimit"
-                        :http-request="fileUploadArticle"
-                    >
-                        <el-icon><Plus /></el-icon>
+                    <el-upload v-model:file-list="fileList" list-type="picture-card" :auto-upload="true" :limit="1"
+                        :on-exceed="fileExceedsLimit" :http-request="fileUploadArticle">
+                        <el-icon>
+                            <Plus />
+                        </el-icon>
                     </el-upload>
 
                 </el-form-item>
@@ -397,7 +396,7 @@ const deleteArticle = async (row) => {
                             :key="quilleditorKey"
                             >
                         </quill-editor> -->
-                        <editor v-model="articleModel.content" @input="(val)=> {articleModel.content=val}"></editor>
+                        <editor v-model="articleModel.content" @input="(val) => { articleModel.content = val }"></editor>
                     </div>
                 </el-form-item>
                 <el-form-item>
@@ -452,11 +451,13 @@ const deleteArticle = async (row) => {
         }
     }
 }
+
 .editor {
-  width: 100%;
-  :deep(.ql-editor) {
-    min-height: 200px;
-  }
+    width: 100%;
+
+    :deep(.ql-editor) {
+        min-height: 200px;
+    }
 }
 
 .avatar-uploader .el-upload {
@@ -466,9 +467,11 @@ const deleteArticle = async (row) => {
     position: relative;
     overflow: hidden;
 }
+
 .avatar-uploader .el-upload:hover {
-    border-color: #409EFF;  
+    border-color: #409EFF;
 }
+
 .avatar-uploader-icon {
     font-size: 28px;
     color: #8c939d;
@@ -477,6 +480,7 @@ const deleteArticle = async (row) => {
     line-height: 178px;
     text-align: center;
 }
+
 .avatar {
     width: 178px;
     height: 178px;

+ 0 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/index.html

@@ -1,4 +1,3 @@
-<!doctype html>
 <html lang="en">
   <head>
     <meta charset="UTF-8" />

+ 7 - 7
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/analysis/index.vue

@@ -51,7 +51,7 @@ const dateOptions = [
 
 type PromptType = {
   permission?: 0 | 1 | 2 | 3;
-  date?: 0 | 1 | 2;
+  date?: 0 | 1 | 2 | any;
   sliceDate: [Date, Date];
 };
 
@@ -171,7 +171,7 @@ watchEffect(() => {
           <el-select
             size="small"
             :model-value="bulletinPrompt.permission"
-            @change="(value) => (bulletinPrompt.permission = value)"
+            @change="(value: any) => (bulletinPrompt.permission = value)"
           >
             <el-option
               v-for="permission in permissionOptions"
@@ -185,7 +185,7 @@ watchEffect(() => {
             ref="select1"
             size="small"
             :model-value="bulletinPrompt.date"
-            @change="(value) => (bulletinPrompt.date = value)"
+            @change="(value: any) => (bulletinPrompt.date = value)"
           >
             <el-option v-for="date in dateOptions" :label="date.label" :value="date.value" />
             <el-option label="自定义" value="ignore" disabled>
@@ -275,7 +275,7 @@ watchEffect(() => {
                 clearable
                 size="small"
                 :model-value="summaryPrompt.permission"
-                @change="(value) => (summaryPrompt.permission = value)"
+                @change="(value: any) => (summaryPrompt.permission = value)"
               >
                 <el-option
                   v-for="permission in permissionOptions"
@@ -290,7 +290,7 @@ watchEffect(() => {
                 clearable
                 size="small"
                 :model-value="summaryPrompt.date"
-                @change="(value) => (summaryPrompt.date = value)"
+                @change="(value: any) => (summaryPrompt.date = value)"
               >
                 <el-option v-for="date in dateOptions" :label="date.label" :value="date.value" />
                 <el-option label="自定义" value="ignore" disabled>
@@ -378,7 +378,7 @@ watchEffect(() => {
                 clearable
                 size="small"
                 :model-value="stagePrompt.permission"
-                @change="(value) => (stagePrompt.permission = value)"
+                @change="(value: any) => (stagePrompt.permission = value)"
               >
                 <el-option
                   v-for="permission in permissionOptions"
@@ -393,7 +393,7 @@ watchEffect(() => {
                 clearable
                 size="small"
                 :model-value="stagePrompt.date"
-                @change="(value) => (stagePrompt.date = value)"
+                @change="(value: any) => (stagePrompt.date = value)"
               >
                 <el-option v-for="date in dateOptions" :label="date.label" :value="date.value" />
                 <el-option label="自定义" value="ignore" disabled>

+ 4 - 4
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/corpreport/index.vue

@@ -17,7 +17,7 @@ import { downloadFile } from '@/utils/tools';
 const isLoading = ref(false);
 const dataSource = ref([]);
 const form = reactive({ type: 1, date: undefined, member: undefined });
-const memberOptions = ref([]);
+const memberOptions: any = ref([]);
 // 0 客户总量  1 客户转化率
 const dataType = ref<0 | 1>(0);
 
@@ -69,7 +69,7 @@ const queryOverall = async (payload?: RequestProps) => {
   const { data = [] } = await getOverallData(payload);
   isLoading.value = false;
 
-  dataSource.value = data.map((d) => ({
+  dataSource.value = data.map((d: any) => ({
     dealRate: d.dealRate * 100,
     customerDeal: d.customerDeal,
     customertotal: d.customertotal,
@@ -98,7 +98,7 @@ const queryConversion = async (payload?: RequestProps) => {
   const { data = [] } = await getConversionData(payload);
   isLoading.value = false;
 
-  dataSource.value = data.map((d) => ({
+  dataSource.value = data.map((d: any) => ({
     name: form.type === 1 ? d.name : d.departmentName,
     dealRate: d.dealRate * 100
   }));
@@ -122,7 +122,7 @@ watchEffect(() => {
 watchEffect(async () => {
   const { data = [] } = form.type === 1 ? await getStaffData() : await getDepartmentData();
 
-  memberOptions.value = data.map((d) => ({
+  memberOptions.value = data.map((d: any) => ({
     name: form.type === 1 ? d.name : d.departmentName,
     id: form.type === 1 ? d.id : d.departmentId
   }));

+ 57 - 22
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/header/header.vue

@@ -7,8 +7,7 @@
     <div v-for="(routerItem, routerItemIdex) in routerList" @click="setCurrentRouter(routerItem)"
       :class="`border-b-2 border-transparent hover:border-white p-2 mr-4 cursor-pointer multipleyHeader ${activeRouter?.path === routerItem.path ? 'border-white' : ''}`"
       :key="routerItem.path" ref="childDivs" v-show="visibleItems.includes(routerItemIdex)">
-      <div v-if="routerItem.children && routerItem.children.length <= 0 && routerItem?.isMenu"
-         class="text-nowrap">
+      <div v-if="routerItem.children && routerItem.children.length <= 0 && routerItem?.isMenu" class="text-nowrap">
         {{ routerItem.name }}
       </div>
       <div v-if="routerItem.children && routerItem.children.length > 0" class="flex justify-center items-center">
@@ -48,7 +47,7 @@
     </div>
   </div>
   <div class="flex flex-row justify-start items-center text-white header-right">
-    <el-badge :value="12" :max="99" class="ml-4 cursor-pointer h-[26px]">
+    <el-badge :value="numberOfLogos" :max="99" class="ml-4 cursor-pointer h-[26px]" :show-zero="false">
       <el-icon :size="26" @click="newsDrawer = true">
         <Bell />
       </el-icon>
@@ -81,29 +80,46 @@
   </el-drawer>
 
   <!-- 消息 -->
-  <el-drawer v-model="newsDrawer" modal-class="drawerVisClass" :with-header="false" size="45%">
-    <div class="w-full h-full">
-      <el-table :data="newsDrawerTableData" style="width: 100%" v-loading="newsDrawerLoading">
-        <el-table-column prop="msg" label="消息内容">
-          <template #default="scope">
-            <el-link type="primary" :underline="false" @click="toDetail(scope.row)">{{ scope.row.msg }}</el-link>
-          </template>
-        </el-table-column>
-        <el-table-column prop="checked" label="状态" width="100">
-          <template #default="scope">
-            <el-tag :type="scope.row.checked ? 'success' : 'danger'">
-              {{ scope.row.checked ? '已读' : '未读' }}
-            </el-tag>
+  <el-drawer v-model="newsDrawer" modal-class="drawerVisClass" :with-header="false" size="50%">
+    <div class="w-full h-full flex flex-row" v-loading="newsDrawerLoading">
+      <div class="w-full h-full">
+        <el-table :data="newsDrawerTableData" style="flex1" border>
+          <el-table-column prop="msg" label="消息内容">
+            <template #default="scope">
+              <el-link type="primary" :underline="false" @click="toDetail(scope.row)">{{ scope.row.msg }}</el-link>
+            </template>
+          </el-table-column>
+          <el-table-column prop="checked" label="状态" width="100">
+            <template #default="scope">
+              <el-tag :type="scope.row.checked ? 'success' : 'danger'">
+                {{ scope.row.checked ? '已读' : '未读' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column prop="time" label="时间" width="140" />
+        </el-table>
+      </div>
+      
+      <div class="messageStyle">
+        <el-dropdown>
+          <span class="el-dropdown-link">
+            <el-icon class="el-icon--right">
+              <el-icon><MoreFilled /></el-icon>
+            </el-icon>
+          </span>
+          <template #dropdown>
+            <el-dropdown-menu>
+              <el-dropdown-item @click="oneClickRead()" :disabled="numberOfLogos <= 0">一键已读</el-dropdown-item>
+            </el-dropdown-menu>
           </template>
-        </el-table-column>
-        <el-table-column prop="time" label="时间" width="140" />
-      </el-table>
+        </el-dropdown>
+      </div>
     </div>
   </el-drawer>
 </template>
 
 <!-- /information/list -->
-  
+
 <script lang="ts" setup>
 import { onMounted, ref, watchEffect, watch } from 'vue';
 import { RouteRecordRaw, useRouter, useRoute } from 'vue-router';
@@ -127,6 +143,7 @@ const newsDrawerTableData = ref<any[]>([])
 const drawerVis = ref(false)
 const newsDrawer = ref(false)
 const newsDrawerLoading = ref(false)
+const numberOfLogos = ref(0)
 
 const updateVisibleItems = () => {
   const parentWidth = (parentDiv.value?.offsetWidth && parentDiv.value?.offsetWidth - 150) || 10;
@@ -224,6 +241,7 @@ const getNewsDrawerTableData = () => {
         time: formatDate(new Date(item.time))
       }
     })
+    numberOfLogos.value = (data || []).filter((item: any) => !item.checked).length
     newsDrawerTableData.value = data
   }).catch(err => {
     newsDrawerTableData.value = []
@@ -233,13 +251,24 @@ const getNewsDrawerTableData = () => {
   })
 }
 
+const oneClickRead = () => {
+  newsDrawerLoading.value = true
+  post(`/information/checkAll`).then(_res => {
+    getNewsDrawerTableData()
+  }).catch(err => {
+    console.log(err, '<==== 失败')
+  }).finally(() => {
+    newsDrawerLoading.value = false
+  })
+}
+
 const toDetail = (row: any) => {
   console.log(row, '<=== 点击数据')
   const { id, type, path } = row
   post(`/information/check`, { id }).then(res => {
     console.log(res, '<=== 成功')
     getNewsDrawerTableData()
-    if(path) {
+    if (path) {
       router.push({ path });
     }
   }).catch(err => {
@@ -268,8 +297,12 @@ watchEffect(() => {
   );
 });
 </script>
-  
+
 <style scoped lang="scss">
+.messageStyle {
+  margin: 15px;
+  margin-left: 100px;
+}
 .trademark {
   font-size: 20px;
 }
@@ -304,11 +337,13 @@ watchEffect(() => {
   .drawerVisBtn {
     margin-top: 10px;
     border-top: 1px solid #999;
+
     div {
       text-align: center;
       line-height: 40px;
       color: #fff;
       cursor: pointer;
+
       &:hover {
         background: #086597;
       }

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/login.vue

@@ -2,7 +2,7 @@
   <div class="loginView w-screen h-screen overflow-hidden flex">
     <div class="w-96 bg-white m-auto border-t-8 border-[#075985] shadow-xl rounded-md pl-9 pr-9">
       <div class="m-auto pt-4">
-        <img class="w-1/5 h-1/5 m-auto" :src="loginLogo" alt="">
+        <img class="w-1/5 m-auto" :src="loginLogo" alt="">
       </div>
       <h2 class="text-xl text-center pt-4 font-bold">客户管家</h2>
       <el-form class="pt-4" ref="ruleFormRef" :model="ruleForm" :rules="rules">

+ 2 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/vite.config.ts

@@ -3,7 +3,8 @@ import vue from '@vitejs/plugin-vue';
 
 import { resolve } from 'path';
 
-const target = 'http://192.168.2.28:10010';
+// const target = 'http://192.168.2.28:10010';
+const target = 'http://192.168.2.17:10010';
 // const target = "http://127.0.0.1:10010";
 // const target = "http://192.168.2.178:10010";
 // const target = 'http://47.101.180.183:10010';

+ 14 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/config/MyExitCodeGenerator.java

@@ -0,0 +1,14 @@
+package com.management.platform.config;
+
+import org.springframework.boot.ExitCodeGenerator;
+import org.springframework.stereotype.Component;
+
+@Component
+public class MyExitCodeGenerator implements ExitCodeGenerator {
+    @Override
+    public int getExitCode() {
+        System.out.println("Spring Boot shutting down.");
+        return 0;
+    }
+}
+

+ 15 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/DepartmentVO.java

@@ -1,5 +1,6 @@
 package com.management.platform.entity.vo;
 
+import com.management.platform.entity.Department;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
@@ -23,4 +24,18 @@ public class DepartmentVO {
     private List<String> otherManagerIds;
     private Integer ddDeptid;
     private Integer pushToSap;
+
+    public static DepartmentVO convertFromDepartment(Department department) {
+        DepartmentVO vo = new DepartmentVO()
+                .setId(department.getDepartmentId())
+                .setManagerId(department.getManagerId())
+                .setLabel(department.getDepartmentName())
+                .setParentId(department.getSuperiorId())
+                .setPushToSap(department.getPushToSap())
+                .setCorpwxDeptid(department.getCorpwxDeptid())
+                .setReportAuditUserid(department.getReportAuditUserid())
+                .setDdDeptid(department.getDdDeptid())
+                .setSeq(department.getSeq());
+        return vo;
+    }
 }

+ 6 - 6
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ContractServiceImpl.java

@@ -132,12 +132,12 @@ public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> i
             if (pageIndex!=null){
                 pageStart = (pageIndex -1) * pageSize;
             }
-            if (StringUtils.isNotBlank(number)){
-                number = "%" + number + "%";
-            }
-            if (StringUtils.isNotBlank(name)){
-                name = "%" + name + "%";
-            }
+//            if (StringUtils.isNotBlank(number)){
+//                number = "%" + number + "%";
+//            }
+//            if (StringUtils.isNotBlank(name)){
+//                name = "%" + name + "%";
+//            }
             List<Contract> contracts = contractMapper.selectContract(user.getCompanyId(), pageStart, pageSize, number, name , typeName , status, startDate,endDate, paymentStartDate, paymentEndDate, secTypeId,customerOrg,finishStatus);
             Long totalCnt = contractMapper.selectContractCnt(user.getCompanyId(), number, name, typeName, status, startDate, endDate, paymentStartDate, paymentEndDate, secTypeId,customerOrg,finishStatus);
             for (Contract contract : contracts) {

+ 43 - 11
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DepartmentServiceImpl.java

@@ -1013,6 +1013,7 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
             List users = result.get("user");
             List depts = result.get("dept");
             if (users.size()!=0){
+                //按人员匹配的情况
                 List<User> realUser = userMapper.selectList(new QueryWrapper<User>().in("corpwx_userid", users));
                 if (realUser.size()!=0){
                     List<DepartmentVO> listById = new ArrayList<>();
@@ -1043,22 +1044,40 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
                 }
             }
             if (depts.size()!=0){
+                //按部门匹配的情况
                 List<Department> departmentList = departmentMapper.selectList(new QueryWrapper<Department>().in("corpwx_deptid", depts).eq("company_id",companyId));
-                List<Department> allDepartmentList = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id",companyId));
-                List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId).eq("is_active",1));
-                List<DepartmentOtherManager> departmentOtherManagerList = departmentOtherManagerMapper.selectList(new QueryWrapper<DepartmentOtherManager>().eq("company_id", companyId));
-                //结果列表
+//                List<Department> allDepartmentList = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id",companyId));
+//                List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId).eq("is_active",1));
+//                List<DepartmentOtherManager> departmentOtherManagerList = departmentOtherManagerMapper.selectList(new QueryWrapper<DepartmentOtherManager>().eq("company_id", companyId));
+//                //结果列表
+//                List<DepartmentVO> list = new ArrayList<>();
+//                List<Department> rootDepartments = allDepartmentList.stream().filter(dept -> dept.getSuperiorId() == null).collect(Collectors.toList());
+//                rootDepartments.forEach(root->{
+//                    DepartmentVO rootDeptVO = formatDepartmentToVO(root, departmentOtherManagerList);
+//                    list.add(rootDeptVO);
+//                    fillSubDepartmentList(allDepartmentList, rootDeptVO, departmentOtherManagerList);
+//                });
                 List<DepartmentVO> list = new ArrayList<>();
-                List<Department> rootDepartments = departmentList.stream().filter(dept -> dept.getSuperiorId() == null).collect(Collectors.toList());
-                rootDepartments.forEach(root->{
-                    DepartmentVO rootDeptVO = formatDepartmentToVO(root, departmentOtherManagerList);
-                    list.add(rootDeptVO);
-                    fillSubDepartmentList(allDepartmentList, rootDeptVO, departmentOtherManagerList);
+                departmentList.forEach(dept->{
+                    DepartmentVO departmentVO = DepartmentVO.convertFromDepartment(dept);
+                    list.add(departmentVO);
                 });
+                //从allDepartmentList中找到departmentList中的部门,并组装成树形结构,节点类型为DepartmentVO
+//                for (Department department : departmentList) {
+//                    DepartmentVO departmentVO = DepartmentVO.convertFromDepartment(department);
+//                    Integer parentId = departmentVO.getParentId();
+//                    if (parentId != null) {
+//                        DepartmentVO parentToRootAsTree = findParentToRootAsTree(allDepartmentList, departmentVO);
+//                        list.add(parentToRootAsTree);
+//                    } else {
+//                        //根节点
+//                        list.add(departmentVO);
+//                    }
+//                }
                 //处理部门下人员列表
-                List<DepartmentVO> userListWithDept = getUserListWithDept(userList, list);
+//                List<DepartmentVO> userListWithDept = getUserListWithDept(userList, list);
                 HashMap<String, Object> data = new HashMap<>();
-                data.put("data",userListWithDept);
+                data.put("data",list);
                 data.put("nextCursor","");
                 msg.data = data;
                 return msg;
@@ -1090,6 +1109,19 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
         }
     }
 
+    public DepartmentVO findParentToRootAsTree(List<Department> allDeptList, DepartmentVO deptVO) {
+        Integer parentId = deptVO.getParentId();
+        if (parentId == null) {
+            return deptVO;
+        }
+        Department parentDept = allDeptList.stream().filter(dept -> dept.getDepartmentId().equals(parentId)).findFirst().get();
+        DepartmentVO parentDeptVO = DepartmentVO.convertFromDepartment(parentDept);
+        ArrayList arrayList = new ArrayList();
+        arrayList.add(deptVO);
+        parentDeptVO.setChildren(arrayList);
+        return findParentToRootAsTree(allDeptList, parentDeptVO);
+    }
+
     public List<DepartmentVO> getUserListWithDept(List<User> userList,List<DepartmentVO> departmentVOList ){
         if(departmentVOList!=null&&departmentVOList.size()>0){
             for (DepartmentVO departmentVO : departmentVOList) {

+ 70 - 79
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -6121,8 +6121,6 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId));
             if (companyId == 4281) {
                 //苏州博海,需要导出未填写的记录
-                //计算从endDate到startDate的工作日数组
-                List<LocalDate> workDays = WorkDayCalculateUtils.getWorkDaysListInRange(startDate, endDate, 0);
                 //allReportByDate针对每一个员工,列表中没有的工作日要补上
                 HttpRespMsg noReportMsg = getNoReportUserList(request, startDate, endDate, null);
                 List<UserDailyWorkItem> noReportUserList = (List<UserDailyWorkItem>)noReportMsg.data;
@@ -6139,7 +6137,6 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 }
             }
             for (Map<String, Object> map : allReportByDate) {
-                long p1 = System.currentTimeMillis();
                 List<String> item=new ArrayList<>();
                 item.add(String.valueOf(rowNum));
                 item.add((String) map.get("jobNumber"));
@@ -6245,8 +6242,6 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     createDate = (String) map.get("createDate");
                 }
                 item.add(createDate);
-//                item.add(new SimpleDateFormat("yyyy-MM-dd")
-//                        .format((java.sql.Date) map.get("createDate")));
                 item.add(map.get("duration").toString());
                 if (timeType.getMultiWorktime() == 1) {
                     if ((Integer)map.get("multiWorktime") == 1) {
@@ -6481,95 +6476,91 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                         } else if (String.valueOf(map.get("state")).equals("-1")) {
                             item.add("导入待审核");
                         } else {
-                            //部门审核
-                            if (String.valueOf(map.get("isDeptAudit")).equals("1")) {
-                                String deptAuditorId = map.get("deptAuditorName") + "";
-                                String departmentName = map.get("departmentName") + "";
-                                for (User userItem : userList) {
-                                    if (userItem.getId().equals(deptAuditorId)) {
-                                        if (needCorpWxTranslate) {
-                                            String deptAuditorName = "$userName=" + userItem.getCorpwxRealUserid() + "$";
-                                            departmentName = "$departmentName=" + departmentName + "$";
-                                            if (timeType.getReportAuditType() == 4) {
-                                                departmentName = map.get("buDepartmentName") + "";
-                                                departmentName = "$departmentName=" + departmentName + "$";
-                                                item.add("待项目所属BU[" + departmentName + "](" + deptAuditorName + ")审核");
-                                            } else {
-                                                item.add("待" + departmentName + "(" + deptAuditorName + ")审核");
-                                            }
-                                        }else if (dingding!=null&&dingding.getContactNeedTranslate()==1) {
-                                            String deptAuditorName = "$userName=" + userItem.getDingdingUserid() + "$";
-                                            departmentName = "$departmentName=" + departmentName + "$";
-                                            if (timeType.getReportAuditType() == 4) {
-                                                departmentName = map.get("buDepartmentName") + "";
-                                                departmentName = "$departmentName=" + departmentName + "$";
-                                                item.add("待项目所属BU[" + departmentName + "](" + deptAuditorName + ")审核");
-                                            } else {
-                                                item.add("待" + departmentName + "(" + deptAuditorName + ")审核");
+                            //项目和部门并行审核模式
+                            if (timeType.getReportAuditType() == 7) {
+                                String str = "待";
+                                if (String.valueOf(map.get("projectAuditState")).equals("0")) {
+                                    String projectAuditorName = map.get("projectAuditorName") + "";
+                                    if (needCorpWxTranslate) {
+                                        for (User userItem : userList) {
+                                            if (userItem.getId().equals(map.get("projectAuditorId"))) {
+                                                projectAuditorName = "$userName=" + userItem.getCorpwxRealUserid() + "$";
+                                                break;
                                             }
-                                        } else {
-                                            if (timeType.getReportAuditType() == 4) {
-                                                departmentName = map.get("buDepartmentName") + "";
-                                                item.add("待项目所属BU[" + departmentName + "](" + userItem.getName() + ")审核");
-                                            } else {
-                                                item.add("待" + departmentName + "(" + userItem.getName() + ")审核");
+                                        }
+                                    }
+                                    str += "项目审核人("+projectAuditorName+")";
+                                }
+                                if (String.valueOf(map.get("departmentAuditState")).equals("0")) {
+                                    String deptAuditorId = map.get("deptAuditorName") + "";
+                                    for (User userItem : userList) {
+                                        if (userItem.getId().equals(deptAuditorId)) {
+                                            String deptAuditorName = userItem.getName();
+                                            if (needCorpWxTranslate) {
+                                                deptAuditorName = "$userName=" + userItem.getCorpwxRealUserid() + "$";
                                             }
+                                            if (str.length() > 1) str += "、";
+                                            str += "部门审核人("+deptAuditorName+")";
+                                            break;
                                         }
-                                        break;
                                     }
                                 }
+                                str += "审核";
+                                item.add(str);
                             } else {
-                                //项目审核或分组审核
-                                if (timeType.getReportAuditType() == 7) {
-                                    //项目和部门并行审核模式
-                                    String str = "待";
-                                    if (String.valueOf(map.get("projectAuditState")).equals("0")) {
-                                        String projectAuditorName = map.get("projectAuditorName") + "";
-                                        if (needCorpWxTranslate) {
-                                            for (User userItem : userList) {
-                                                if (userItem.getId().equals(map.get("projectAuditorId"))) {
-                                                    projectAuditorName = "$userName=" + userItem.getCorpwxRealUserid() + "$";
-                                                    break;
+                                if (String.valueOf(map.get("isDeptAudit")).equals("1")) {
+                                    String deptAuditorId = map.get("deptAuditorName") + "";
+                                    String departmentName = map.get("departmentName") + "";
+                                    for (User userItem : userList) {
+                                        if (userItem.getId().equals(deptAuditorId)) {
+                                            if (needCorpWxTranslate) {
+                                                String deptAuditorName = "$userName=" + userItem.getCorpwxRealUserid() + "$";
+                                                departmentName = "$departmentName=" + departmentName + "$";
+                                                if (timeType.getReportAuditType() == 4) {
+                                                    departmentName = map.get("buDepartmentName") + "";
+                                                    departmentName = "$departmentName=" + departmentName + "$";
+                                                    item.add("待项目所属BU[" + departmentName + "](" + deptAuditorName + ")审核");
+                                                } else {
+                                                    item.add("待" + departmentName + "(" + deptAuditorName + ")审核");
+                                                }
+                                            }else if (dingding!=null&&dingding.getContactNeedTranslate()==1) {
+                                                String deptAuditorName = "$userName=" + userItem.getDingdingUserid() + "$";
+                                                departmentName = "$departmentName=" + departmentName + "$";
+                                                if (timeType.getReportAuditType() == 4) {
+                                                    departmentName = map.get("buDepartmentName") + "";
+                                                    departmentName = "$departmentName=" + departmentName + "$";
+                                                    item.add("待项目所属BU[" + departmentName + "](" + deptAuditorName + ")审核");
+                                                } else {
+                                                    item.add("待" + departmentName + "(" + deptAuditorName + ")审核");
+                                                }
+                                            } else {
+                                                if (timeType.getReportAuditType() == 4) {
+                                                    departmentName = map.get("buDepartmentName") + "";
+                                                    item.add("待项目所属BU[" + departmentName + "](" + userItem.getName() + ")审核");
+                                                } else {
+                                                    item.add("待" + departmentName + "(" + userItem.getName() + ")审核");
                                                 }
                                             }
+                                            break;
                                         }
-                                        str += "项目审核人("+projectAuditorName+")";
                                     }
-                                    if (String.valueOf(map.get("departmentAuditState")).equals("0")) {
-                                        String deptAuditorId = map.get("deptAuditorName") + "";
+                                } else if (String.valueOf(map.get("projectAuditState")).equals("0") || String.valueOf(map.get("groupAuditState")).equals("0")) {
+                                    String projectAuditorName = map.get("projectAuditorName") + "";
+                                    String projectAuditorId = map.get("projectAuditorId") + "";
+                                    if (needCorpWxTranslate||(dingding!=null&&dingding.getContactNeedTranslate()==1)) {
                                         for (User userItem : userList) {
-                                            if (userItem.getId().equals(deptAuditorId)) {
-                                                String deptAuditorName = userItem.getName();
-                                                if (needCorpWxTranslate) {
-                                                    deptAuditorName = "$userName=" + userItem.getCorpwxRealUserid() + "$";
+                                            if (userItem.getId().equals(projectAuditorId)) {
+                                                if(needCorpWxTranslate){
+                                                    projectAuditorName = "$userName=" + userItem.getCorpwxUserid() + "$";
+                                                }else if(dingding!=null&&dingding.getContactNeedTranslate()==1){
+                                                    projectAuditorName = "$userName=" + userItem.getDingdingUserid() + "$";
                                                 }
-                                                if (str.length() > 1) str += "、";
-                                                str += "部门审核人("+deptAuditorName+")";
+                                                item.add("待"+(companyId == 469?"部门主管":"项目审核人") + "(" + projectAuditorName + ")审核");
                                                 break;
                                             }
                                         }
-                                    }
-                                    str += "审核";
-                                    item.add(str);
-                                } else {
-                                    if (String.valueOf(map.get("projectAuditState")).equals("0") || String.valueOf(map.get("groupAuditState")).equals("0")) {
-                                        String projectAuditorName = map.get("projectAuditorName") + "";
-                                        String projectAuditorId = map.get("projectAuditorId") + "";
-                                        if (needCorpWxTranslate||(dingding!=null&&dingding.getContactNeedTranslate()==1)) {
-                                            for (User userItem : userList) {
-                                                if (userItem.getId().equals(projectAuditorId)) {
-                                                    if(needCorpWxTranslate){
-                                                        projectAuditorName = "$userName=" + userItem.getCorpwxUserid() + "$";
-                                                    }else if(dingding!=null&&dingding.getContactNeedTranslate()==1){
-                                                        projectAuditorName = "$userName=" + userItem.getDingdingUserid() + "$";
-                                                    }
-                                                    item.add("待"+(companyId == 469?"部门主管":"项目审核人") + "(" + projectAuditorName + ")审核");
-                                                    break;
-                                                }
-                                            }
-                                        } else {
-                                            item.add("待"+(companyId == 469?"部门主管":"项目审核人") + "(" + projectAuditorName + ")审核");
-                                        }
+                                    } else {
+                                        item.add("待"+(companyId == 469?"部门主管":"项目审核人") + "(" + projectAuditorName + ")审核");
                                     }
                                 }
                             }

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java

@@ -2120,7 +2120,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                     }else{
                         System.err.println("==================通讯录查询请求无userid列表===================");
                     }
-                    System.err.println(respJson.toString());
+                    System.err.println("通讯录搜索返回结果=="+respJson.toString());
                     Boolean is_last = respJson.getBoolean("is_last");
                     if (!is_last){
                         itemCursor = respJson.getString("next_cursor");

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ContractMapper.xml

@@ -66,7 +66,7 @@
         <if test="customerOrg!=null">
             and cc.customer_org like  CONCAT('%', #{customerOrg}, '%')
         </if>
-        order by contract.id desc
+        order by contract.number desc
         <if test="pageStart!=null and pageSize!=null">
             limit #{pageStart},#{pageSize}
         </if>

+ 2 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/.env.development

@@ -0,0 +1,2 @@
+NODE_ENV="development"
+VUE_APP_URL="http://192.168.5.184:10010"

+ 3 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/.env.production

@@ -0,0 +1,3 @@
+# 配置生产地址,就是你将来发布上线的地址
+NODE_ENV="production"
+VUE_APP_URL="http://192.168.5.184:10010"

+ 22 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/.gitignore

@@ -0,0 +1,22 @@
+.DS_Store
+node_modules
+/dist
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+.svn
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 49 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/README.bak.md

@@ -0,0 +1,49 @@
+# 知识体系
+
+#### 封装 axios
+
+1. 使用拦截器统一处理请求和响应数据
+2. 挂载到原型上
+
+#### 上拉加载更多
+
+1. vant 的组件
+2. 设置初始高度,不然 bug 很严重
+
+#### 懒加载
+
+1. 懒加载是什么
+2. 如何实现
+
+#### 环境配置
+
+1. 根目录新建 .env.development (测试环境) 文件
+
+   ```
+   VUE_APP_URL="http://132.232.87.95:3000/api"
+   ```
+
+   然后新建。env.production(生产环境)文件
+
+   ```
+   VUE_APP_URL="http://132.232.94.151:3000/api"
+   ```
+
+2. 配置 package.json
+
+   ```
+    "scripts": {
+       "serve": "vue-cli-service serve --model",
+       "build": "vue-cli-service build --model",
+       "lint": "vue-cli-service lint"
+     },
+   ```
+
+3. 项目中通过 process.env.VUE_APP_URL  访问 VUE_APP_URL 的值,不同的环境取到的值不一样
+
+#### 打包部署
+
+#### 移动端适配
+
+1. amfe-flexib 设置 root 元素字体大小
+2. pxtorem  px 转 rem

+ 140 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/README.md

@@ -0,0 +1,140 @@
+# vue 移动端模板
+
+#### 启动项目
+1. npm i 安装依赖
+1. npm run serve 启动项目
+1. cd server  (接口目录)
+1. npm i 
+1. npm run dev
+
+
+>#### 核心知识体系简介
+1. vue-cli3 脚手架
+    * 创建项目
+    * 开发环境和生产环境配置
+    * 配置跨域
+    
+2. vue-router 路由
+    * 路由配置
+    * 子路由配置
+    * 路由守卫,设置页面标题和根据登录状态判断是否允许进入特定页面
+    * 对router-link使用active-class,高亮当前路由
+    
+3. vuex 跨组件通信
+    * vuex 配置
+    * vuex 持久化
+    * vuex 使用
+    
+4. rem 移动端适配
+    * 通过 amfe-flexibe 设置 root 元素的字体大小
+    * 通过 pxtorem 把 px 转成 rem, 无需手动书写 rem
+    
+5. axios 配置
+    * 使用拦截器配置 baseURL 和给请求头加上 token
+    * 使用拦截器对返回的数据进行处理
+    * 挂载到 vue 原型上,方便使用
+    
+6. promise 使用
+    
+    * 在项目中使用 async await 把异步变成同步,编写和阅读更舒服
+    
+7. 有赞 vant-ui 库
+    * 导航栏
+    * 单元格
+    * loading
+    * ......
+    
+8. 使用keep-alive组件缓存某些组件(新增)
+
+9. 添加小型服务器接口,用来编写本项目所需接口
+
+    
+
+>####  vue-cli3 脚手架
+1. 具体操作,请移步[vue-cli3文档官网]( [https://cli.vuejs.org/zh/guide/installation.html](https://links.jianshu.com/go?to=https%3A%2F%2Fcli.vuejs.org%2Fzh%2Fguide%2Finstallation.html)
+)
+2. **开发环境和生产环境配置**
+  * 根目录新建两文件 .env.development => 开发环境配置  .env.production => 生产环境配置
+![image.png](https://upload-images.jianshu.io/upload_images/7177443-4f2c42f1c1bc4439.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+文件内容
+
+```
+// .env.development
+VUE_APP_URL="https://www.easy-mock.com/mock/5cd62747d3a84206275d58d1/huruqing/api"
+```
+
+```
+// .env.production
+VUE_APP_URL="https://www.easy-mock.com/mock/5cd62747d3a84206275d58d1/huruqing/api"
+```
+
+3. **package.json 配置**
+vue-cli3默认已经给你配置好了model, 开发环境对应development, 生产环境对应production,如果你不知道model,请移步[webpack文档官网]([https://www.webpackjs.com/](https://www.webpackjs.com/)
+)
+![image.png](https://upload-images.jianshu.io/upload_images/7177443-5e9e447da363cfca.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+4. 在你的项目中,通过  process.env.VUE_APP_URL 可以访问到你在环境配置文件中设置的变量
+![](https://upload-images.jianshu.io/upload_images/7177443-d585aa842e655950.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+![开发环境中的变量](https://upload-images.jianshu.io/upload_images/7177443-02325513adfb846f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+
+>####  vue-router 路由
+这里主要讲一下路由守卫的配置,先上图
+![路由配置](https://upload-images.jianshu.io/upload_images/7177443-5f45913a5d70bf4d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+下面是路由守卫配置
+![路由守卫](https://upload-images.jianshu.io/upload_images/7177443-a935a3506fd9f567.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+
+>####  vuex 跨组件通信
+1. 项目中有以下几个地方用到了 vuex
+    * 设置登录状态
+    * 设置用户名
+    * 保存 token
+2. 以登录为里,做个简单说明
+![](https://upload-images.jianshu.io/upload_images/7177443-825e2e816a49413b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+登录成功时,修改登陆状态为 true
+![image.png](https://upload-images.jianshu.io/upload_images/7177443-906c4cc3e5713830.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+退出登录时,修改登录状态为 false
+![](https://upload-images.jianshu.io/upload_images/7177443-1da2a2e9208c1872.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+4. 获取 store 中 state 设置的变量通过 mapGetters, 看图
+![](https://upload-images.jianshu.io/upload_images/7177443-61be719b7d9c8a43.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+![在模板中使用](https://upload-images.jianshu.io/upload_images/7177443-8b2c372f88a0f59e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+
+3. vuex 持久化
+    * 使用 vuex-persistedstate 插件对 vuex 的状态持久化
+    * 等你的页面刷新时,状态依然存在
+    * 本质上是这个插件帮你把状态都存到了 localStorage
+配置方法,以下是最简单的配置
+![](https://upload-images.jianshu.io/upload_images/7177443-0aa53dbad9057879.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+使用了 vuex-persistedstate 插件后,store 里的状态都存到了 localStorage
+![image.png](https://upload-images.jianshu.io/upload_images/7177443-9cf6e3db49baf726.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+
+>#### rem 移动端适配
+适配原理我就不多说了,不清楚请看我的另外一篇文章[用rem编写移动端自适应网页](https://www.jianshu.com/p/91ac1690be89)(https://www.jianshu.com/p/91ac1690be89),这里说一下在vue-cli3中是如何配置的
+1. 安装 amfe-flexible 插件 ```npm i amfe-flexible --save-dev```
+2. 在 main.js 中导入
+![ipone6](https://upload-images.jianshu.io/upload_images/7177443-05c1792eb5cfab79.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+3. 此时你的应用的 html 会自动根据手机的尺寸设置了 font-size, 如图
+![](https://upload-images.jianshu.io/upload_images/7177443-5ea467230b5426e0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+![](https://upload-images.jianshu.io/upload_images/7177443-ee3e3fda5ec57b39.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+4. 配置 pxtorem 插件,能帮你自动把 rem 转成 px, 具体配置如下,在项目根目录下的 vue.config.js(没有则新建)
+里进行配置,如图
+![](https://upload-images.jianshu.io/upload_images/7177443-2b6e79201971d86d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+
+>####  axios 配置
+1. axios 拦截器
+能帮我们对数据进行一些统一的处理,比如后台给我们的数据里都是把数据包在 data 对象里面,而使用 axios, 则又会再用 data 把返回的数据再包一层,如果不统一处理以下,用起来很不爽。
+2. 设置请求头,后台识别用户经常使用 token, 我们登陆的时候能拿到后台返回的 token, 然后存入 store 里,当我们发送请求时,我们可以给请求头统一加上 token, 如图
+![](https://upload-images.jianshu.io/upload_images/7177443-2a42eb0010cde4a1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+3. 把 axios 的实例挂载到 vue 的实例上
+![](https://upload-images.jianshu.io/upload_images/7177443-5163a952efbac676.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+发请求的时候,只需要使用 this.$axios.get 或者 this.$axios.post 就行了,是不是很方便
+![](https://upload-images.jianshu.io/upload_images/7177443-5a0bd9bbec047aa7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+
+>#### Promise 的使用
+promise 是个好东西,可以把异步变同步,在项目中使用 async await 编写代码,那叫一个爽,具体用法如下:
+![](https://upload-images.jianshu.io/upload_images/7177443-9f357fbd0a04215a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
+
+>#### 有赞 vant-ui 库
+有赞是搞电商开发的,在公众号和小程序模板界算是做得比较不错的,vant-ui是他们开源出来的一个ui库,同时他们还有小程序的ui库,感兴趣的小伙伴可以去[看看](https://youzan.github.io/vant/)(https://youzan.github.io/vant/)
+
+>
+
+

+ 24 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/babel.config.js

@@ -0,0 +1,24 @@
+module.exports = {
+  presets: [["@babel/preset-env", { modules: false }]],
+  plugins: [
+    [
+      "import",
+      {
+        libraryName: "vant",
+        libraryDirectory: "es",
+        // 指定样式路径
+        // style: name => `${name}/style/less`
+        style: true,
+      },
+      "vant",
+    ],
+    ["@babel/plugin-syntax-dynamic-import"],
+    [
+      "component",
+      {
+        libraryName: "element-ui",
+        styleLibraryName: "theme-chalk",
+      },
+    ],
+  ],
+};

+ 1 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/build.bat

@@ -0,0 +1 @@
+npm run build

文件差异内容过多而无法显示
+ 13281 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/package-lock.json


+ 65 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/package.json

@@ -0,0 +1,65 @@
+{
+  "name": "maizuo-h6",
+  "version": "0.1.0",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve --model",
+    "dev": "vue-cli-service serve --model",
+    "prod": "vue-cli-service serve --model production",
+    "build": "vue-cli-service build --model",
+    "push": "git add . && git commit -m'xxx' && git push",
+    "lint": "vue-cli-service lint"
+  },
+  "dependencies": {
+    "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+    "babel-plugin-import": "^1.13.3",
+    "core-js": "^2.6.12",
+    "css-loader": "^3.6.0",
+    "dingtalk-jsapi": "^2.13.42",
+    "echarts": "^4.9.0",
+    "element-ui": "^2.15.13",
+    "font-awesome": "^4.7.0",
+    "jquery": "^3.6.1",
+    "pdfh5": "^1.4.2",
+    "style-loader": "^1.3.0",
+    "vue": "^2.6.12",
+    "vuex-persistedstate": "^2.7.1",
+    "weixin-js-sdk": "^1.6.0"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "^3.12.1",
+    "@vue/cli-plugin-eslint": "^3.12.1",
+    "@vue/cli-service": "^4.5.13",
+    "amfe-flexible": "^2.2.1",
+    "autoprefixer": "^9.8.6",
+    "axios": "^0.26.1",
+    "babel-eslint": "^10.1.0",
+    "babel-plugin-component": "^1.1.1",
+    "eslint": "^5.16.0",
+    "eslint-plugin-vue": "^5.2.3",
+    "less": "^3.13.1",
+    "less-loader": "^5.0.0",
+    "postcss-loader": "^3.0.0",
+    "postcss-pxtorem": "^4.0.1",
+    "vant": "^2.12.18",
+    "vue-html5-editor": "^1.1.1",
+    "vue-router": "^3.5.1",
+    "vue-template-compiler": "^2.6.12",
+    "vuex": "^3.6.2"
+  },
+  "eslintConfig": {
+    "root": true,
+    "env": {
+      "node": true
+    },
+    "extends": [],
+    "rules": {},
+    "parserOptions": {
+      "parser": "babel-eslint"
+    }
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions"
+  ]
+}

文件差异内容过多而无法显示
+ 2 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/public/axios.min.js


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/public/favicon.ico


+ 87 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/public/index.html

@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <!-- <meta name="viewport" content="width=device-width,initial-scale=1.0"> -->
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
+    <link rel="shortcut icon" type="image/x-icon" href="./favicon.ico"/>
+    <title>车间生产管家</title>
+    <link rel="stylesheet" href="https://at.alicdn.com/t/font_1456778_1mgn5degp7t.css">
+    <!-- 引入企业微信js -->
+    <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js" referrerpolicy="origin"></script>
+    <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js" referrerpolicy="origin"></script>
+    <!-- 接入飞书 -->
+    <script type="text/javascript" src="https://lf1-cdn-tos.bytegoofy.com/goofy/lark/op/h5-js-sdk-1.5.16.js"></script>
+    <!-- <script src="https://s.url.cn/qqun/qun/qqweb/m/qun/confession/js/vconsole.min.js "></script> -->
+
+    <script>
+        // function IsPC() { 
+        //     var userAgentInfo = navigator.userAgent;
+        //     var Agents = ["Android", "iPhone",
+        //                 "SymbianOS", "Windows Phone",
+        //                 "iPad", "iPod"];
+        //     var flag = true;
+        //     for (var v = 0; v < Agents.length; v++) {
+        //         if (userAgentInfo.indexOf(Agents[v]) > 0) {
+        //             flag = false;
+        //             break;
+        //         }
+        //     }
+        //     return flag;
+        // }
+        // var urls = window.location.href
+
+        // // 尝试定向回去, 不行要删除
+        // if(urls.indexOf('jsapi/init') != '-1') {
+        //     location.href = urls.split('jsapi/init')[0]
+        // }
+        // // 尝试定向回去, 不行要删除
+
+        // var flag = IsPC(); //true为PC端,false为手机端
+        // if(flag) {
+        //     console.log('触发')
+        //     // 当前地址为车间生产管家移动端就跳转到车间生产管家官网
+        //     if(urls.indexOf('mobworktime.ttkuaiban') != '-1') {
+        //         location.href = 'https://worktime.ttkuaiban.com';
+        //     } else {
+        //         location.href = 'http://mldworktime.ttkuaiban.com:9097/';
+        //     }
+        // }
+    </script>
+    <style>
+        .dateSelectCell .van-cell__value{
+            -webkit-box-flex: 2;
+            -webkit-flex: 2;
+            flex: 2;
+        }
+        /* 清除浮动 */
+        .clearfix:after{
+            content: ""; 
+            display: block; 
+            height: 0; 
+            clear: both; 
+            visibility: hidden;  
+        }
+        .clearfix {
+            /* 触发 hasLayout */ 
+            zoom: 1; 
+        }
+        .popupSearch .van-search__content {
+            background-color: #FFFFFF !important;
+        }
+        .chooseSomeoneo_group .van-radio__label, .chooseSomeoneo_group .van-checkbox__label {
+          flex: 1 !important;
+        }
+    </style>
+</head>
+
+<body>
+    <noscript>
+        <strong>非常抱歉,网页丢了</strong>
+    </noscript>
+    <div id="app"></div>
+    
+</body>
+
+</html>

+ 186 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/App.vue

@@ -0,0 +1,186 @@
+<template>
+    <div class="h100">
+        <keep-alive>
+            <router-view v-if="$route.meta.keepAlive"></router-view>
+        </keep-alive>
+        <router-view v-if="!$route.meta.keepAlive"></router-view>
+    </div>
+</template>
+
+<script>
+import $ from 'jquery'
+export default {
+    name: "app",
+    created() { },
+    mounted() {
+      let width=$("body").width();
+      console.log(width)
+      if(width>=1200){
+        let fontsize=width/1920*40;//fontsize为当前屏幕的基数字体,相对于设计稿计算得到的。
+        $("html").css("font-size",`${fontsize}px`)
+      }
+      if(width<=750){
+        let fontsize=width/400*40;
+        $("html").css("font-size",`${fontsize}px`)
+      }
+      //当加载页面的时候设置生效
+      window.onresize = () => {
+        return (() => {
+          let width=$("body").width();
+          if(width>=1200){
+            let fontsize=width/1920*40;
+            $("html").css("font-size",`${fontsize}px`)
+          }
+          if(width<=750){
+            let fontsize=width/400*40;
+            $("html").css("font-size",`${fontsize}px`)
+          }
+        })()
+      }
+    }
+};
+</script>
+
+<style>
+  * {
+    font-family: '微软雅黑';
+  }
+  .h100 {
+    height: 100vh;
+    box-sizing: border-box;
+  }
+  /* flex */
+  .flexCoum {
+    display: flex;
+    flex-wrap: wrap;
+    flex-direction: column;
+    height: 100%;
+  }
+  /* 超出隐藏 */
+  .textBeyondHiding {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+
+  .flexCoum-box {
+    flex: 1;
+    overflow: auto;
+  }
+  /* 去除滚动条 */
+  .contentRoll::-webkit-scrollbar { width: 0 !important }
+  .contentRoll { -ms-overflow-style: none; }
+  .contentRoll { overflow: -moz-scrollbars-none; }
+
+  .popupDiv {
+    background: #F4F4F4;
+    position: relative;
+    height: 100%;
+    width: 100%;
+    display: flex;
+    flex-direction: column;
+  }
+  .popupSearch {
+    width: 100%;
+  }
+  .popupCon {
+    width: 100%;
+    overflow: auto;
+    position: relative;
+  }
+  .paddingDiv {
+    box-sizing: border-box;
+    margin: 0 15px;
+  }
+  .popupTitle {
+    color: #333333;
+    padding: 0 30px;
+    position: relative;
+    line-height: 20px;
+  }
+  .popupTitle::after {
+    content: '';
+    width: 3px;
+    height: 100%;
+    border-radius: 3px;
+    background: #409eff;
+    position: absolute;
+    top: 0;
+    left: 15px;
+  }
+  .popupItem {
+    background: #FFFFFF;
+    padding: 10px 10px;
+    border-radius: 6px;
+    margin-top: 14px;
+    position: relative;
+  }
+  .marginTop {
+    margin-top: 15px;
+  }
+  .paddingTop {
+    padding-top: 10px;
+  }
+  .popupItem p {
+    width: 100%;
+    overflow: hidden;
+    white-space:nowrap;
+    text-overflow: ellipsis;
+    line-height: 22px;
+  }
+  .popupItemOne {
+    font-size: 15px;
+    color: #333;
+  }
+  .popupItemTwo {
+    font-size: 13px;
+    color: #999;
+    margin-top: 10px;
+  }
+  .popupItemIcon {
+    position: absolute;
+    right: 7px;
+    top: 50%;
+    font-size: 20px;
+    margin-top: -10px;
+    color: #999;
+  }
+
+  .popupConBox {
+    box-sizing: border-box;
+  }
+  .borderNone {
+    border-radius: 0;
+  }
+  .marginNone {
+    margin: 0 !important;
+  }
+  .popupBtn {
+    padding: 0 15px;
+    margin-top: 10px;
+    margin-bottom: 15px;
+  }
+  .conBorder {
+    width: auto !important;
+    margin: 0 15px;
+    border-radius: 10px;
+    box-sizing: border-box;
+  }
+  
+  .userNameClass_left {
+    display: inline-block;
+    width: 100px;
+  }
+  .userNameClass_right {
+    display: inline-block;
+    width: 150px;
+    float: right;
+    text-align: right;
+    overflow: hidden;
+    white-space:nowrap;
+    text-overflow: ellipsis;
+  }
+</style>
+
+
+

+ 33 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/app.js

@@ -0,0 +1,33 @@
+export function  initWxConfig(vm){
+    var url="/api" + "/wxcorp/getCorpWXConfig";
+    var curUrl=location.href.split("#")[0];
+    var user = JSON.parse(localStorage.userInfo);
+    var params="url="+curUrl+"&token="+user.id;
+    
+    
+    vm.$ajax.post(url,params).then(res=>{
+        var data=res.data;
+        wx.config({ 
+          beta: true,
+          debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
+          appId: data.appid, // 必填,公众号的唯一标识 
+          timestamp: data.timestamp, // 必填,生成签名的时间戳 
+          nonceStr: data.noncestr, // 必填,生成签名的随机串 
+          signature: data.signature, // 必填,签名,见附录1 
+          jsApiList: [
+              'chooseImage',
+              'previewImage',
+              'uploadImage',
+              'downloadImage',
+              'previewFile',
+              'getLocation',
+         ] 
+        });
+        wx.error(function (res) {
+            console.log("调用微信jsapi返回的状态:"+res.errMsg);
+        });
+    }).catch(function(error) {
+        //vm.errorToast(error,1000);
+        console.info(error);
+    })
+}

+ 75 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/collapse.js

@@ -0,0 +1,75 @@
+
+const elTransition =
+  "0.3s height ease-in-out, 0.3s padding-top ease-in-out, 0.3s padding-bottom ease-in-out";
+const Transition = {
+  "before-enter"(el) {
+    el.style.transition = elTransition;
+    if (!el.dataset) el.dataset = {};
+ 
+    el.dataset.oldPaddingTop = el.style.paddingTop;
+    el.dataset.oldPaddingBottom = el.style.paddingBottom;
+ 
+    el.style.height = 0;
+    el.style.paddingTop = 0;
+    el.style.paddingBottom = 0;
+  },
+ 
+  enter(el) {
+    el.dataset.oldOverflow = el.style.overflow;
+    if (el.scrollHeight !== 0) {
+      el.style.height = el.scrollHeight + "px";
+      el.style.paddingTop = el.dataset.oldPaddingTop;
+      el.style.paddingBottom = el.dataset.oldPaddingBottom;
+    } else {
+      el.style.height = "";
+      el.style.paddingTop = el.dataset.oldPaddingTop;
+      el.style.paddingBottom = el.dataset.oldPaddingBottom;
+    }
+ 
+    el.style.overflow = "hidden";
+  },
+ 
+  "after-enter"(el) {
+    el.style.transition = "";
+    el.style.height = "";
+    el.style.overflow = el.dataset.oldOverflow;
+  },
+ 
+  "before-leave"(el) {
+    if (!el.dataset) el.dataset = {};
+    el.dataset.oldPaddingTop = el.style.paddingTop;
+    el.dataset.oldPaddingBottom = el.style.paddingBottom;
+    el.dataset.oldOverflow = el.style.overflow;
+ 
+    el.style.height = el.scrollHeight + "px";
+    el.style.overflow = "hidden";
+  },
+ 
+  leave(el) {
+    if (el.scrollHeight !== 0) {
+      el.style.transition = elTransition;
+      el.style.height = 0;
+      el.style.paddingTop = 0;
+      el.style.paddingBottom = 0;
+    }
+  },
+ 
+  "after-leave"(el) {
+    el.style.transition = "";
+    el.style.height = "";
+    el.style.overflow = el.dataset.oldOverflow;
+    el.style.paddingTop = el.dataset.oldPaddingTop;
+    el.style.paddingBottom = el.dataset.oldPaddingBottom;
+  }
+};
+ 
+export default {
+  name: "collapseTransition",
+  functional: true,
+  render(h, { children }) {
+    const data = {
+      on: Transition
+    };
+    return h("transition", data, children);
+  }
+};

二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/icon/kefu.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/1.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/jz1.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/jz2.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/jz3.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/jz4.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/r1.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/r2.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/r3.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/r4.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/MovieDetails/r5.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/alt.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/chong.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/cover/1.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/cover/2.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/cover/3.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/cover/4.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/cover/5.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/group/hb1.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/group/hb2.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/group/tx1.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/group/tx2.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/group/tx3.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/group/tx4.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/home/banner_1.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/home/banner_2.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/home/banner_3.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/home/check.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/home/edit.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/home/more.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/home/my.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/home/wait.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/index/banner4.jpeg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/index/banner_1.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/index/banner_2.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/index/banner_3.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/kf.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/login_logo.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/logo.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/not.jpeg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/null.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/orderList1.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/orderList2.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/beij.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/cl.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/dt.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/hb.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/head_back.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/p.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/qb.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/tg.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/tx.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/userHead.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/personal/yhk.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/poster/1.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/poster/2.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/poster/3.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/poster/4.jpg


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/qwcode.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/qx.png


二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/img/qxbj.png


文件差异内容过多而无法显示
+ 1 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/shju.json


+ 363 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/style/common.less

@@ -0,0 +1,363 @@
+body {
+  background: #f4f4f4;
+  font-size: 16px !important;
+}
+
+.bd {
+  border: 1px solid;
+}
+
+.bdb {
+  border-bottom: 1px solid #ebebeb;
+}
+
+.ovh {
+  overflow: hidden;
+}
+
+.h100pc {
+  height: 100%;
+}
+
+.w100pc {
+  width: 100%;
+}
+
+.dsn {
+  display: none;
+}
+
+.fixed {
+  position: fixed;
+}
+
+.rel {
+  position: relative;
+}
+
+.abs {
+  position: absolute;
+}
+
+.tac {
+  text-align: center;
+}
+
+.lh15 {
+  line-height: 1.5;
+}
+
+/* 颜色 */
+.f999 {
+  color: #999;
+}
+
+.fff {
+  color: #ffffff;
+}
+
+.orange {
+  color: #ff5f16;
+}
+
+/* 背景颜色 */
+.bg-green {
+  background: green;
+}
+
+.bg-gray {
+  background: gray;
+}
+
+.bg-fff {
+  background: #ffffff;
+}
+
+/* 弹性盒子公共样式 */
+/* 排列方向-横向排列 */
+.flex {
+  display: flex;
+}
+
+/* 纵向排列 */
+.flex2 {
+  display: flex;
+  flex-direction: column;
+}
+
+/* 水平居中,垂直居中 */
+.fcc {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+/* 两端对齐 */
+.jc-sb {
+  justify-content: space-between;
+}
+
+/* 分散对齐 */
+.jc-sa {
+  justify-content: space-around;
+}
+
+/* 垂直居中 */
+.aic {
+  align-items: center;
+}
+
+/* 分配剩余空间 */
+.fg1 {
+  flex-grow: 1;
+}
+
+.fg2 {
+  flex-grow: 2;
+}
+
+
+/* 字体设置 */
+.f0 {
+  font-size: 0px
+}
+
+.f8 {
+  font-size: 8px
+}
+
+.f10 {
+  font-size: 10px
+}
+
+.f12 {
+  font-size: 12px
+}
+
+.f14 {
+  font-size: 14px
+}
+
+.f16 {
+  font-size: 16px
+}
+
+.f18 {
+  font-size: 18px
+}
+
+.f20 {
+  font-size: 20px
+}
+
+.f22 {
+  font-size: 22px
+}
+
+.f24 {
+  font-size: 24px
+}
+
+.f26 {
+  font-size: 26px
+}
+
+/* margin-top设置 */
+.mt-5 {
+  margin-top: 5px;
+}
+
+.mt-10 {
+  margin-top: 10px;
+}
+
+.mt-15 {
+  margin-top: 15px;
+}
+
+.mt-20 {
+  margin-top: 20px;
+}
+
+.mt-25 {
+  margin-top: 25px;
+}
+
+.mt-30 {
+  margin-top: 30px;
+}
+
+/* margin-bottom设置 */
+.mb-5 {
+  margin-bottom: 5px;
+}
+
+.mb-10 {
+  margin-bottom: 10px;
+}
+
+.mb-15 {
+  margin-bottom: 15px;
+}
+
+.mb-20 {
+  margin-bottom: 20px;
+}
+
+.mb-25 {
+  margin-bottom: 25px;
+}
+
+.mb-30 {
+  margin-bottom: 30px;
+}
+
+/* margin-left设置 */
+.ml-5 {
+  margin-left: 5px;
+}
+
+.ml-10 {
+  margin-left: 10px;
+}
+
+.ml-15 {
+  margin-left: 15px;
+}
+
+.ml-20 {
+  margin-left: 20px;
+}
+
+.ml-25 {
+  margin-left: 25px;
+}
+
+.ml-30 {
+  margin-left: 30px;
+}
+
+/* margin-right设置 */
+.mr-5 {
+  margin-right: 5px;
+}
+
+.mr-10 {
+  margin-right: 10px;
+}
+
+.mr-15 {
+  margin-right: 15px;
+}
+
+.mr-20 {
+  margin-right: 20px;
+}
+
+.mr-25 {
+  margin-right: 25px;
+}
+
+.mr-30 {
+  margin-right: 30px;
+}
+
+/* padding-top设置 */
+.pt-5 {
+  padding-top: 5px;
+}
+
+.pt-10 {
+  padding-top: 10px;
+}
+
+.pt-15 {
+  padding-top: 15px;
+}
+
+.pt-20 {
+  padding-top: 20px;
+}
+
+.pt-25 {
+  padding-top: 25px;
+}
+
+.pt-30 {
+  padding-top: 30px;
+}
+
+/* padding-bottom设置 */
+.pb-5 {
+  padding-bottom: 5px;
+}
+
+.pb-10 {
+  padding-bottom: 10px;
+}
+
+.pb-15 {
+  padding-bottom: 15px;
+}
+
+.pb-20 {
+  padding-bottom: 20px;
+}
+
+.pb-25 {
+  padding-bottom: 25px;
+}
+
+.pb-30 {
+  padding-bottom: 30px;
+}
+
+/* padding-left设置 */
+.pl-5 {
+  padding-left: 5px;
+}
+
+.pl-10 {
+  padding-left: 10px;
+}
+
+.pl-15 {
+  padding-left: 15px;
+}
+
+.pl-20 {
+  padding-left: 20px;
+}
+
+.pl-25 {
+  padding-left: 25px;
+}
+
+.pl-30 {
+  padding-left: 30px;
+}
+
+/* padding-right设置 */
+.pr-5 {
+  padding-right: 5px;
+}
+
+.pr-10 {
+  padding-right: 10px;
+}
+
+.pr-15 {
+  padding-right: 15px;
+}
+
+.pr-20 {
+  padding-right: 20px;
+}
+
+.pr-25 {
+  padding-right: 25px;
+}
+
+.pr-30 {
+  padding-right: 30px;
+}

+ 539 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/style/font/demo.css

@@ -0,0 +1,539 @@
+/* Logo 字体 */
+@font-face {
+  font-family: "iconfont logo";
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
+}
+
+.logo {
+  font-family: "iconfont logo";
+  font-size: 160px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+/* tabs */
+.nav-tabs {
+  position: relative;
+}
+
+.nav-tabs .nav-more {
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  height: 42px;
+  line-height: 42px;
+  color: #666;
+}
+
+#tabs {
+  border-bottom: 1px solid #eee;
+}
+
+#tabs li {
+  cursor: pointer;
+  width: 100px;
+  height: 40px;
+  line-height: 40px;
+  text-align: center;
+  font-size: 16px;
+  border-bottom: 2px solid transparent;
+  position: relative;
+  z-index: 1;
+  margin-bottom: -1px;
+  color: #666;
+}
+
+
+#tabs .active {
+  border-bottom-color: #f00;
+  color: #222;
+}
+
+.tab-container .content {
+  display: none;
+}
+
+/* 页面布局 */
+.main {
+  padding: 30px 100px;
+  width: 960px;
+  margin: 0 auto;
+}
+
+.main .logo {
+  color: #333;
+  text-align: left;
+  margin-bottom: 30px;
+  line-height: 1;
+  height: 110px;
+  margin-top: -50px;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.main .logo a {
+  font-size: 160px;
+  color: #333;
+}
+
+.helps {
+  margin-top: 40px;
+}
+
+.helps pre {
+  padding: 20px;
+  margin: 10px 0;
+  border: solid 1px #e7e1cd;
+  background-color: #fffdef;
+  overflow: auto;
+}
+
+.icon_lists {
+  width: 100% !important;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.icon_lists li {
+  width: 100px;
+  margin-bottom: 10px;
+  margin-right: 20px;
+  text-align: center;
+  list-style: none !important;
+  cursor: default;
+}
+
+.icon_lists li .code-name {
+  line-height: 1.2;
+}
+
+.icon_lists .icon {
+  display: block;
+  height: 100px;
+  line-height: 100px;
+  font-size: 42px;
+  margin: 10px auto;
+  color: #333;
+  -webkit-transition: font-size 0.25s linear, width 0.25s linear;
+  -moz-transition: font-size 0.25s linear, width 0.25s linear;
+  transition: font-size 0.25s linear, width 0.25s linear;
+}
+
+.icon_lists .icon:hover {
+  font-size: 100px;
+}
+
+.icon_lists .svg-icon {
+  /* 通过设置 font-size 来改变图标大小 */
+  width: 1em;
+  /* 图标和文字相邻时,垂直对齐 */
+  vertical-align: -0.15em;
+  /* 通过设置 color 来改变 SVG 的颜色/fill */
+  fill: currentColor;
+  /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
+      normalize.css 中也包含这行 */
+  overflow: hidden;
+}
+
+.icon_lists li .name,
+.icon_lists li .code-name {
+  color: #666;
+}
+
+/* markdown 样式 */
+.markdown {
+  color: #666;
+  font-size: 14px;
+  line-height: 1.8;
+}
+
+.highlight {
+  line-height: 1.5;
+}
+
+.markdown img {
+  vertical-align: middle;
+  max-width: 100%;
+}
+
+.markdown h1 {
+  color: #404040;
+  font-weight: 500;
+  line-height: 40px;
+  margin-bottom: 24px;
+}
+
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+  color: #404040;
+  margin: 1.6em 0 0.6em 0;
+  font-weight: 500;
+  clear: both;
+}
+
+.markdown h1 {
+  font-size: 28px;
+}
+
+.markdown h2 {
+  font-size: 22px;
+}
+
+.markdown h3 {
+  font-size: 16px;
+}
+
+.markdown h4 {
+  font-size: 14px;
+}
+
+.markdown h5 {
+  font-size: 12px;
+}
+
+.markdown h6 {
+  font-size: 12px;
+}
+
+.markdown hr {
+  height: 1px;
+  border: 0;
+  background: #e9e9e9;
+  margin: 16px 0;
+  clear: both;
+}
+
+.markdown p {
+  margin: 1em 0;
+}
+
+.markdown>p,
+.markdown>blockquote,
+.markdown>.highlight,
+.markdown>ol,
+.markdown>ul {
+  width: 80%;
+}
+
+.markdown ul>li {
+  list-style: circle;
+}
+
+.markdown>ul li,
+.markdown blockquote ul>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown>ul li p,
+.markdown>ol li p {
+  margin: 0.6em 0;
+}
+
+.markdown ol>li {
+  list-style: decimal;
+}
+
+.markdown>ol li,
+.markdown blockquote ol>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown code {
+  margin: 0 3px;
+  padding: 0 5px;
+  background: #eee;
+  border-radius: 3px;
+}
+
+.markdown strong,
+.markdown b {
+  font-weight: 600;
+}
+
+.markdown>table {
+  border-collapse: collapse;
+  border-spacing: 0px;
+  empty-cells: show;
+  border: 1px solid #e9e9e9;
+  width: 95%;
+  margin-bottom: 24px;
+}
+
+.markdown>table th {
+  white-space: nowrap;
+  color: #333;
+  font-weight: 600;
+}
+
+.markdown>table th,
+.markdown>table td {
+  border: 1px solid #e9e9e9;
+  padding: 8px 16px;
+  text-align: left;
+}
+
+.markdown>table th {
+  background: #F7F7F7;
+}
+
+.markdown blockquote {
+  font-size: 90%;
+  color: #999;
+  border-left: 4px solid #e9e9e9;
+  padding-left: 0.8em;
+  margin: 1em 0;
+}
+
+.markdown blockquote p {
+  margin: 0;
+}
+
+.markdown .anchor {
+  opacity: 0;
+  transition: opacity 0.3s ease;
+  margin-left: 8px;
+}
+
+.markdown .waiting {
+  color: #ccc;
+}
+
+.markdown h1:hover .anchor,
+.markdown h2:hover .anchor,
+.markdown h3:hover .anchor,
+.markdown h4:hover .anchor,
+.markdown h5:hover .anchor,
+.markdown h6:hover .anchor {
+  opacity: 1;
+  display: inline-block;
+}
+
+.markdown>br,
+.markdown>p>br {
+  clear: both;
+}
+
+
+.hljs {
+  display: block;
+  background: white;
+  padding: 0.5em;
+  color: #333333;
+  overflow-x: auto;
+}
+
+.hljs-comment,
+.hljs-meta {
+  color: #969896;
+}
+
+.hljs-string,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-strong,
+.hljs-emphasis,
+.hljs-quote {
+  color: #df5000;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-type {
+  color: #a71d5d;
+}
+
+.hljs-literal,
+.hljs-symbol,
+.hljs-bullet,
+.hljs-attribute {
+  color: #0086b3;
+}
+
+.hljs-section,
+.hljs-name {
+  color: #63a35c;
+}
+
+.hljs-tag {
+  color: #333333;
+}
+
+.hljs-title,
+.hljs-attr,
+.hljs-selector-id,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo {
+  color: #795da3;
+}
+
+.hljs-addition {
+  color: #55a532;
+  background-color: #eaffea;
+}
+
+.hljs-deletion {
+  color: #bd2c00;
+  background-color: #ffecec;
+}
+
+.hljs-link {
+  text-decoration: underline;
+}
+
+/* 代码高亮 */
+/* PrismJS 1.15.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+code[class*="language-"],
+pre[class*="language-"] {
+  color: black;
+  background: none;
+  text-shadow: 0 1px white;
+  font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+  text-align: left;
+  white-space: pre;
+  word-spacing: normal;
+  word-break: normal;
+  word-wrap: normal;
+  line-height: 1.5;
+
+  -moz-tab-size: 4;
+  -o-tab-size: 4;
+  tab-size: 4;
+
+  -webkit-hyphens: none;
+  -moz-hyphens: none;
+  -ms-hyphens: none;
+  hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+@media print {
+
+  code[class*="language-"],
+  pre[class*="language-"] {
+    text-shadow: none;
+  }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+  padding: 1em;
+  margin: .5em 0;
+  overflow: auto;
+}
+
+:not(pre)>code[class*="language-"],
+pre[class*="language-"] {
+  background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre)>code[class*="language-"] {
+  padding: .1em;
+  border-radius: .3em;
+  white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+  color: slategray;
+}
+
+.token.punctuation {
+  color: #999;
+}
+
+.namespace {
+  opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+  color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+  color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+  color: #9a6e3a;
+  background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+  color: #07a;
+}
+
+.token.function,
+.token.class-name {
+  color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+  color: #e90;
+}
+
+.token.important,
+.token.bold {
+  font-weight: bold;
+}
+
+.token.italic {
+  font-style: italic;
+}
+
+.token.entity {
+  cursor: help;
+}

文件差异内容过多而无法显示
+ 1706 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/style/font/demo_index.html


+ 279 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/style/font/iconfont.css

@@ -0,0 +1,279 @@
+@font-face {
+  font-family: "iconfont"; /* Project id 2390497 */
+  src: url('iconfont.woff2?t=1653388410123') format('woff2'),
+       url('iconfont.woff?t=1653388410123') format('woff'),
+       url('iconfont.ttf?t=1653388410123') format('truetype');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.firerock-icondakajilu:before {
+  content: "\e6e1";
+}
+
+.firerock-iconguanlian:before {
+  content: "\e674";
+}
+
+.firerock-iconusers:before {
+  content: "\e70a";
+}
+
+.firerock-iconquanxian1:before {
+  content: "\e615";
+}
+
+.firerock-iconxitong-:before {
+  content: "\e616";
+}
+
+.firerock-iconkehu:before {
+  content: "\e67e";
+}
+
+.firerock-iconwj-qjd:before {
+  content: "\e70e";
+}
+
+.firerock-icondaibanshixiang:before {
+  content: "\ec4e";
+}
+
+.firerock-icondaiban:before {
+  content: "\e64b";
+}
+
+.firerock-icongongshitongji:before {
+  content: "\e614";
+}
+
+.firerock-iconshenhetongguo:before {
+  content: "\e6a0";
+}
+
+.firerock-iconshenhebohui:before {
+  content: "\e6c6";
+}
+
+.firerock-icondaibandengdaishenhe:before {
+  content: "\e612";
+}
+
+.firerock-iconjianzhugongchenglei:before {
+  content: "\e61e";
+}
+
+.firerock-icongantetu:before {
+  content: "\e6a1";
+}
+
+.firerock-iconkehuguanli:before {
+  content: "\e60f";
+}
+
+.firerock-iconliucheng:before {
+  content: "\e634";
+}
+
+.firerock-iconright:before {
+  content: "\e60e";
+}
+
+.firerock-iconApp_New_Line:before {
+  content: "\e6e3";
+}
+
+.firerock-icon0:before {
+  content: "\e609";
+}
+
+.firerock-iconInsertLine:before {
+  content: "\e61d";
+}
+
+.firerock-iconmima:before {
+  content: "\e611";
+}
+
+.firerock-iconmima1:before {
+  content: "\e608";
+}
+
+.firerock-iconyanzhengma:before {
+  content: "\e60d";
+}
+
+.firerock-icondot:before {
+  content: "\e60b";
+}
+
+.firerock-icondot2:before {
+  content: "\e607";
+}
+
+.firerock-iconbaobiao:before {
+  content: "\e636";
+}
+
+.firerock-iconzuzhijiagou1:before {
+  content: "\e698";
+}
+
+.firerock-icontianbao1:before {
+  content: "\e60a";
+}
+
+.firerock-iconzuzhijiagou:before {
+  content: "\e606";
+}
+
+.firerock-iconzuzhijiegou:before {
+  content: "\e670";
+}
+
+.firerock-iconquanxian:before {
+  content: "\e663";
+}
+
+.firerock-iconbaoxiao:before {
+  content: "\e788";
+}
+
+.firerock-iconbaoxiaodan:before {
+  content: "\e644";
+}
+
+.firerock-icontianbao:before {
+  content: "\e726";
+}
+
+.firerock-iconrecord:before {
+  content: "\e605";
+}
+
+.firerock-icondaoru:before {
+  content: "\e613";
+}
+
+.firerock-icondaochu:before {
+  content: "\e6ab";
+}
+
+.firerock-iconexport:before {
+  content: "\e72d";
+}
+
+.firerock-iconqidong:before {
+  content: "\e63c";
+}
+
+.firerock-iconwancheng:before {
+  content: "\e610";
+}
+
+.firerock-iconcaidan:before {
+  content: "\e6b7";
+}
+
+.firerock-iconshenhe:before {
+  content: "\e604";
+}
+
+.firerock-iconicon-:before {
+  content: "\e6ad";
+}
+
+.firerock-iconrenwu:before {
+  content: "\e64c";
+}
+
+.firerock-iconfengxian:before {
+  content: "\e6a2";
+}
+
+.firerock-iconnormal-ico-ok:before {
+  content: "\e70f";
+}
+
+.firerock-iconicon2:before {
+  content: "\e603";
+}
+
+.firerock-iconfile:before {
+  content: "\e60c";
+}
+
+.firerock-iconex:before {
+  content: "\e65c";
+}
+
+.firerock-iconZip:before {
+  content: "\e9ec";
+}
+
+.firerock-iconJPG:before {
+  content: "\e6ed";
+}
+
+.firerock-iconaudio:before {
+  content: "\e602";
+}
+
+.firerock-icontxt:before {
+  content: "\e741";
+}
+
+.firerock-iconvideo:before {
+  content: "\e771";
+}
+
+.firerock-iconPDF:before {
+  content: "\e61a";
+}
+
+.firerock-iconword:before {
+  content: "\eecf";
+}
+
+.firerock-iconshangchuan:before {
+  content: "\e6fd";
+}
+
+.firerock-iconmiaobiao:before {
+  content: "\ecfa";
+}
+
+.firerock-icontask:before {
+  content: "\e600";
+}
+
+.firerock-iconmeditor-time:before {
+  content: "\e601";
+}
+
+.firerock-icontree:before {
+  content: "\e691";
+}
+
+.firerock-icontongji:before {
+  content: "\e631";
+}
+
+.firerock-iconxiangmu:before {
+  content: "\e617";
+}
+
+.firerock-iconcaiwu:before {
+  content: "\e89c";
+}
+
+.firerock-iconsetting:before {
+  content: "\e672";
+}
+

二进制
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/style/font/iconfont.eot


+ 0 - 0
fhKeeper/formulahousekeeper/timesheet-workshop-h5-stand/src/assets/style/font/iconfont.js


部分文件因为文件数量过多而无法显示