Просмотр исходного кода

Merge branch '2023-3-17-yi_shu_jia' into 11/24SAAS

liushengqiang 2 лет назад
Родитель
Сommit
89a0a40cc0

+ 69 - 0
src/styles/custom.scss

@@ -0,0 +1,69 @@
+.dialog {
+  ::v-deep {
+    .el-dialog {
+      border-radius: 4px;
+      overflow: hidden;
+    }
+    .el-dialog__header {
+      display: flex;
+      flex-shrink: 0;
+      justify-content: space-between;
+      align-items: center;
+      box-sizing: border-box;
+      width: 100%;
+      height: 48px;
+      padding: 0 20px;
+      .el-dialog__title {
+        font-weight: 500;
+        font-size: 16px;
+      }
+      .el-dialog__headerbtn {
+        position: relative;
+        top: 0;
+        right: 0;
+        &::before {
+          position: absolute;
+          display: block;
+          box-sizing: border-box;
+          background-color: transparent;
+          border-radius: 50%;
+          transition: background-color 0.1s cubic-bezier(0, 0, 1, 1);
+          content: "";
+          top: 50%;
+          left: 50%;
+          width: 20px;
+          height: 20px;
+          transform: translate(-50%, -50%);
+        }
+      }
+      .el-dialog__headerbtn:hover {
+        &::before {
+          background-color: rgba(0, 0, 0, 0.5);
+        }
+      }
+      .el-dialog__close {
+        position: relative;
+      }
+    }
+    .el-dialog__body {
+      padding: 10px 20px;
+    }
+    .el-input-group__append {
+      padding: 0 10px;
+    }
+  }
+}
+
+.elForm {
+  ::v-deep {
+    .el-form-item__label {
+      max-width: 100%;
+      color: #4e5969;
+      font-size: 14px;
+      white-space: normal;
+      padding: 0;
+      font-weight: 400;
+      line-height: 32px;
+    }
+  }
+}

+ 7 - 0
src/views/littleArtistCamp/api.js

@@ -28,6 +28,13 @@ export const resetTrainingCamp = data => {
     requestType: 'json',
   })
 }
+// 显示隐藏
+export const tempLittleArtistTrainingCampEnable = data => {
+  return request({
+    url: '/api-web/tempLittleArtistTrainingCamp/enable/' + data,
+    method: 'get'
+  })
+}
 
 // 删除
 export const delTrainingCamp = data => {

+ 34 - 2
src/views/littleArtistCamp/aristCampDetail.vue

@@ -33,6 +33,18 @@
           </el-select>
         </el-form-item>
 
+        <el-form-item prop="standardFlag">
+          <el-select
+            v-model="searchForm.standardFlag"
+            clearable
+            placeholder="打卡状态"
+          >
+            <el-option label="全部" :value="''"></el-option>
+            <el-option label="达标" :value="true"></el-option>
+            <el-option label="未达标" :value="false"></el-option>
+          </el-select>
+        </el-form-item>
+
         <el-form-item>
           <el-button native-type="submit" type="danger">搜索</el-button>
           <el-button native-type="reset" type="primary">重置</el-button>
@@ -63,18 +75,38 @@
           ></el-table-column>
           <el-table-column
             align="center"
+            prop="subjectName"
+            label="声部"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="musicGroupName"
+            label="乐团"
+          ></el-table-column>
+          <el-table-column
+            align="center"
             prop="imGroupName"
             label="群组"
           ></el-table-column>
           <el-table-column align="center" prop="playDay" label="打卡天数">
             <template slot-scope="scope"> {{ scope.row.playDay }}天 </template>
           </el-table-column>
+          <el-table-column align="center" prop="cloudStudySequenceDays" label="最高连续打卡">
+            <template slot-scope="scope"> {{ scope.row.cloudStudySequenceDays || 0 }}天 </template>
+          </el-table-column>
           <el-table-column
             align="center"
             prop="playTime"
             label="训练时长(分钟)"
           >
           </el-table-column>
+          <el-table-column
+            align="center"
+            prop="standardFlag"
+            label="打卡状态"
+          >
+            <template slot-scope="scope">{{scope.row.standardFlag ? '达标' : '未达标'}}</template>
+          </el-table-column>
           <el-table-column align="center" prop="playTime" label="操作">
             <template slot-scope="scope">
               <div>
@@ -112,7 +144,7 @@ export default {
   components: { pagination, artistClock },
   data() {
     return {
-      searchForm: {search:'',imGroupId:''},
+      searchForm: {search:'',imGroupId:'', standardFlag: ''},
       tableList: [],
       imGroupIdList: [],
       title: this.$route.query.name || "",
@@ -168,7 +200,7 @@ export default {
       }
     },
     lookstudentCamp(row) {
-      this.$refs.artistClock.openDioag(row);
+      this.$refs.artistClock.openDioag({...row, campId: this.$route.query.id});
     },
     exportCampDetail() {
       // this.$confirm(`您确定导出"${title}"列表`, "提示", {

+ 42 - 5
src/views/littleArtistCamp/index.vue

@@ -43,6 +43,14 @@
             ></el-option>
           </el-select>
         </el-form-item>
+
+        <el-form-item prop="enableFlag">
+          <el-select v-model="searchForm.enableFlag" placeholder="是否隐藏">
+            <el-option label="显示" :value="1"></el-option>
+            <el-option label="隐藏" :value="0"></el-option>
+          </el-select>
+        </el-form-item>
+
         <el-form-item prop="applyTime">
           <el-date-picker
             v-model.trim="searchForm.applyTime"
@@ -87,7 +95,7 @@
           >
         </auth>
         <auth auths="tempLittleArtistTrainingCamp/queryPageTrainingCampUser">
-          <el-button type="primary" style="margin-bottom: 30px" @click="getRosterList"
+          <el-button type="primary" style="display: none; margin-bottom: 30px" @click="getRosterList"
             >参与名单</el-button
           >
         </auth>
@@ -115,6 +123,13 @@
               </div>
             </template>
           </el-table-column>
+          <el-table-column align="center" prop="studentId" label="是否隐藏">
+            <template slot-scope="scope">
+              <div>
+                {{ scope.row.enableFlag ? '显示' : '隐藏' }}
+              </div>
+            </template>
+          </el-table-column>
           <el-table-column align="center" prop="studentId" label="报名时间段">
             <template slot-scope="scope">
               <div>
@@ -146,13 +161,22 @@
                   <el-button
                     type="text"
                     @click="resetCamp(scope.row)"
-                    v-if="scope.row.state != 'ING' && scope.row.state != 'END'"
+                    v-if="['NOT_START', 'APPLY', 'READY'].includes(scope.row.state)"
                     >修改</el-button
                   >
                 </auth>
                 <auth
+                  :auths="'/tempLittleArtistTrainingCamp/enable'"
+                >
+                  <el-button
+                    type="text"
+                    @click="() => handleChangeState(scope.row)"
+                    >{{ scope.row.enableFlag ? '隐藏' : '显示' }}</el-button
+                  >
+                </auth>
+                <auth
                   auths="tempLittleArtistTrainingCamp/delete"
-                  v-if="scope.row.state == 'READY'"
+                  v-if="['NOT_START', 'APPLY'].includes(scope.row.state)"
                 >
                   <el-button type="text" @click="deleteCamp(scope.row)"
                     >删除</el-button
@@ -184,7 +208,7 @@ import pagination from "@/components/Pagination/index";
 import load from "@/utils/loading";
 import { getTimes } from "@/utils";
 import { campStateList } from "@/utils/searchArray";
-import { getTrainingCampList,delTrainingCamp } from "./api";
+import { getTrainingCampList,delTrainingCamp, tempLittleArtistTrainingCampEnable } from "./api";
 
  import campRosterList from "./models/campRosterList";
 import eidtCamp from "./models/eidtCamp";
@@ -195,8 +219,10 @@ export default {
     return {
       searchForm: {
         search: null,
+        state: null,
         applyTime: [],
         trainTime: [],
+        enableFlag: null
       },
       campStateList,
       tableList: [],
@@ -222,6 +248,13 @@ export default {
     init() {
       this.getList();
     },
+    /** 启用和停用 */
+    handleChangeState(row){
+      tempLittleArtistTrainingCampEnable(row.id)
+      .then(() => {
+        this.getList();
+      })
+    },
     async getList() {
       let { applyTime, trainTime, ...rest } = this.searchForm;
       let params = {
@@ -243,7 +276,11 @@ export default {
       this.rules.page = 1;
       this.getList();
     },
-    onReSet() {},
+    onReSet() {
+      this.$nextTick(() => {
+        this.getList();
+      })
+    },
     lookCamp(row) {
       console.log(row)
       this.$router.push({path:'/operateManager/aristCampDetail',query:{id:row.id,imGroupIds:row.imGroupIds,name:row.name}})

+ 1 - 1
src/views/littleArtistCamp/models/artistClock.vue

@@ -58,7 +58,7 @@ export default {
     async openDioag(row) {
       this.activeRow = row;
       try {
-        const res = await getUserTrainingTime({ userId: row.id });
+        const res = await getUserTrainingTime({ userId: row.id, campId: row.campId });
         this.trainingList = res.data;
         this.trainingList.forEach((item) => {
           const tempDate = dayjs(item.trainingDate).format("YYYY-MM-DD");

+ 151 - 50
src/views/littleArtistCamp/models/eidtCamp.vue

@@ -1,59 +1,98 @@
 <template>
   <div>
     <el-dialog
-      width="520px"
+      class="dialog"
+      width="630px"
       :title="title"
       :visible.sync="lookVisible"
       :before-close="onClose"
     >
-      <el-form :model="formes" label-width="100px" ref="eidtCamp">
+      <el-form class="elForm" label-position="top" :model="formes" label-width="100px" ref="eidtCamp">
         <el-form-item
           label="训练营标题"
-          :rules="[{ required: true, message: '请输入发送内容' }]"
+          :rules="[{ required: true, message: '请输入训练营标题' }]"
           prop="name"
         >
           <el-input class="w100" v-model="formes.name"></el-input>
         </el-form-item>
-        <el-form-item
-          prop="applyTime"
-          label="报名时间"
-          :rules="[{ required: true, message: '请选择报名时间' }]"
-        >
-          <el-date-picker
-            v-model.trim="formes.applyTime"
-            class="w100"
-            type="daterange"
-            value-format="yyyy-MM-dd"
-            @change="
-              () => {
-                formes.trainTime = [];
-              }
-            "
-            range-separator="至"
-            start-placeholder="报名开始日期"
-            end-placeholder="报名结束日期"
-            :picker-options="payDate()"
-          >
-          </el-date-picker>
+        <el-form-item label="适用分部" prop="organIds" :rules="[{ required: true, message: '请选择分部' }]">
+          <el-select style="width: 100% !important;" v-model="formes.organIds" multiple clearable filterable @change="handleChangeOrgan">
+            <el-option :label="o.name" :value="o.id + ''" v-for="(o) in organs" :key="o.id"></el-option>
+          </el-select>
         </el-form-item>
-        <el-form-item
-          prop="trainTime"
-          label="训练时间"
-          :rules="[{ required: true, message: '请选择训练时间' }]"
-        >
-          <el-date-picker
-            v-model.trim="formes.trainTime"
-            type="daterange"
-            value-format="yyyy-MM-dd"
-            class="w100"
-            range-separator="至"
-            start-placeholder="训练开始日期"
-            end-placeholder="训练结束日期"
-            :picker-options="payendTimer"
-          >
-          </el-date-picker>
+        <el-form-item label="适用乐团" prop="musicGroupIds" >
+          <el-select style="width: 100% !important;" v-model="formes.musicGroupIds" multiple clearable filterable>
+            <el-option :label="o.musicGroupName" :value="o.musicGroupId" v-for="(o) in musicGroups" :key="o.musicGroupId"></el-option>
+          </el-select>
         </el-form-item>
-        <el-form-item
+        <div class="wrap">
+          <el-form-item
+            prop="applyTime"
+            label="报名时间"
+            :rules="[{ required: true, message: '请选择报名时间' }]"
+          >
+            <el-date-picker
+              v-model.trim="formes.applyTime"
+              class="w100"
+              type="daterange"
+              value-format="yyyy-MM-dd"
+              @change="
+                () => {
+                  formes.trainTime = [];
+                }
+              "
+              range-separator="至"
+              start-placeholder="报名开始日期"
+              end-placeholder="报名结束日期"
+              :picker-options="payDate()"
+            >
+            </el-date-picker>
+          </el-form-item>
+          <el-form-item
+            prop="trainTime"
+            label="训练时间"
+            :rules="[{ required: true, message: '请选择训练时间' }]"
+          >
+            <el-date-picker
+              v-model.trim="formes.trainTime"
+              type="daterange"
+              value-format="yyyy-MM-dd"
+              class="w100"
+              range-separator="至"
+              start-placeholder="训练开始日期"
+              end-placeholder="训练结束日期"
+              :picker-options="payendTimer"
+            >
+            </el-date-picker>
+          </el-form-item>
+        </div>
+
+        <div class="wrap">
+          <el-form-item label="打卡标准"
+            prop="signStandard"
+            :rules="[
+              { required: true, message: '请输入打卡标准' },
+              { pattern: /^[1-9][0-9]*$/, message: '请输入大于0的正整数',}
+            ]"
+          >
+            <el-input placeholder="请输入打卡标准" v-model="formes.signStandard">
+              <template slot="append">分钟/天</template>
+            </el-input>
+          </el-form-item>
+          <el-form-item label="达标天数" 
+            prop="standardDays"
+            :rules="[
+              { required: true, message: '请输入最低打卡天数' },
+              { pattern: /^[1-9][0-9]*$/, message: '请输入大于0的正整数',}
+              ]"
+          >
+            <el-input placeholder="请输入最低打卡天数" v-model="formes.standardDays">
+              <template slot="append">天</template>
+            </el-input>
+          </el-form-item>
+        </div>
+        
+        <!-- <el-form-item
           label="封面图"
           prop="picUrl"
           :rules="[
@@ -64,15 +103,13 @@
             },
           ]"
         >
-          <!--      v-show="!form.coverImg"  -->
           <upload
             class="uploadImg"
             v-model="formes.picUrl"
             ref="uploadImg"
           ></upload>
-          <!-- <img v-show="form.coverImg" :src="form.coverImg" alt="" width="105px" height="134px" @click="uploadImg"/> -->
           <p style="color: red">格式为jpg、png、gif图片</p>
-        </el-form-item>
+        </el-form-item> -->
       </el-form>
       <div slot="footer" class="dialog-footer">
         <el-button @click="onClose">取 消</el-button>
@@ -85,6 +122,8 @@
 import Upload from "@/components/Upload/index";
 import { addTrainingCamp, resetTrainingCamp } from "../api";
 import { getTimes } from "@/utils";
+import { queryEmployeeOrganByUser } from "@/api/systemManage";
+import { queryOrganMusicInfos } from "@/api/zeroManager";
 let that;
 export default {
   name: "eidtCamp",
@@ -94,12 +133,19 @@ export default {
   data() {
     return {
       title: "",
+      organs: [], // 当前员工分部列表
+      musicGroups: [], // 所选分部的乐团列表
+      timer: '',
       formes: {
         id: "",
         name: "",
         picUrl: "",
         applyTime: [],
         trainTime: [],
+        organIds: [], // 分部,多选
+        musicGroupIds: [], // 适用乐团
+        signStandard: null, // 打开标准
+        standardDays: null, // 达标天数
       },
       lookVisible: false,
       chioseIdList: null,
@@ -112,7 +158,32 @@ export default {
     this.init();
   },
   methods: {
-    init() {},
+    async init() {
+      const res = await queryEmployeeOrganByUser()
+      if (Array.isArray(res?.data)){
+        this.organs = res.data
+      }
+    },
+
+    /** 获取分部乐团列表 */
+    async getOrganMusicInfos(){
+      const organId = (this.formes?.organIds || []).join(',')
+      console.log("🚀 ~ organId:", organId)
+      if (!organId) return;
+      const res = await queryOrganMusicInfos({organId})
+      if (Array.isArray(res?.data)){
+        this.musicGroups = res.data
+      }
+    },
+
+    /** 分部选项改变 */
+    handleChangeOrgan(){
+      this.formes.musicGroupIds = []
+      clearTimeout(this.timer)
+      this.timer = setTimeout(() => {
+        this.getOrganMusicInfos()
+      }, 1000)
+    },
 
     openDioag(row) {
       if (row && row.id) {
@@ -120,9 +191,12 @@ export default {
         this.title = "修改训练营";
         this.formes = {
           ...row,
+          organIds: row.organIds?.split(',')?.filter(Boolean) || [],
+          musicGroupIds: row.musicGroupIds?.split(',')?.filter(Boolean) || [],
           applyTime: [row.applyStartDate, row.applyEndDate],
           trainTime: [row.trainStartDate, row.trainEndDate],
         };
+        this.getOrganMusicInfos()
       } else {
         this.title = "新建训练营";
       }
@@ -133,8 +207,13 @@ export default {
       this.formes = {
         id: "",
         name: "",
+        picUrl: "",
         applyTime: [],
         trainTime: [],
+        organIds: [], // 分部,多选
+        musicGroupIds: [], // 适用乐团
+        signStandard: null, // 打开标准
+        standardDays: null, // 达标天数
       };
       this.$refs["eidtCamp"].resetFields();
       this.lookVisible = false;
@@ -144,9 +223,11 @@ export default {
         if (flag) {
           try {
             if (this.activeRow && this.activeRow.id) {
-              let { applyTime, trainTime, ...rest } = this.formes;
+              let { applyTime, trainTime, organIds,musicGroupIds, ...rest } = this.formes;
               let params = {
                 ...rest,
+                organIds: organIds?.join(','),
+                musicGroupIds: musicGroupIds?.join(','),
                 ...getTimes(applyTime, ["applyStartDate", "applyEndDate"]),
                 ...getTimes(trainTime, ["trainStartDate", "trainEndDate"]),
               };
@@ -155,9 +236,11 @@ export default {
               this.onClose();
               this.$emit("getList");
             } else {
-              let { applyTime, trainTime, ...rest } = this.formes;
+              let { applyTime, trainTime, organIds,musicGroupIds, ...rest } = this.formes;
               let params = {
                 ...rest,
+                organIds: organIds?.join(','),
+                musicGroupIds: musicGroupIds?.join(','),
                 ...getTimes(applyTime, ["applyStartDate", "applyEndDate"]),
                 ...getTimes(trainTime, ["trainStartDate", "trainEndDate"]),
               };
@@ -190,13 +273,13 @@ export default {
       return {
         firstDayOfWeek: 1,
         disabledDate(time) {
-          if (that.formes.applyTime[1]) {
+          if (Array.isArray(that.formes.applyTime) && that.formes.applyTime[1]) {
             return (
-              time.getTime() + 86400000 <=
+              time.getTime() <=
               new Date(that.formes.applyTime[1]).getTime()
             );
           } else {
-            return time.getTime() + 86400000 <= new Date().getTime();
+            return time.getTime() <= new Date().getTime();
           }
         },
       };
@@ -205,7 +288,25 @@ export default {
 };
 </script>
 <style lang="scss" scoped>
+@import '@/styles/custom.scss';
 .w100 {
   width: 100%;
 }
+
+.wrap{
+  display: flex;
+  align-items: center;
+  ::v-deep .el-form-item:not(:last-child){
+    margin-right: 20px;
+    
+  }
+  .el-form-item{
+    flex: 1;
+  }
+  ::v-deep{
+    .el-range-separator{
+      padding: 0;
+    }
+  }
+}
 </style>

+ 29 - 19
src/views/main/cloudDate/exerciseDuration.vue

@@ -43,7 +43,7 @@
           :data-zoom="dataZoom"
         ></ve-histogram>
       </el-tab-pane>
-      <el-tab-pane label="比例图" name="second">
+      <el-tab-pane label="比例图" name="second">
         <ve-histogram
           v-if="activeName == 'second'"
           style="width: 100%"
@@ -96,7 +96,12 @@
             <div>{{ scope.row.trainRate }}%</div>
           </template>
         </el-table-column>
-        <el-table-column align="center" prop="id" label="<60分钟">
+        <el-table-column align="center" prop="id" label="≤10分钟">
+          <template slot-scope="scope">
+            <div>{{ scope.row.train0 }}人</div>
+          </template>
+        </el-table-column>
+        <el-table-column align="center" prop="id" label="10~60分钟">
           <template slot-scope="scope">
             <div>{{ scope.row.train1 }}人</div>
           </template></el-table-column
@@ -164,13 +169,9 @@ import dayjs from "dayjs";
 import histogram from "v-charts/lib/histogram.common";
 import { getNowDateAndMonday, getNowDateAndSunday } from "@/utils/utils";
 import { cloudTeacherNum } from "../api";
-let nowTime = new Date();
-nowTime =
-  nowTime.getFullYear() +
-  "-" +
-  (nowTime.getMonth() + 1) +
-  "-" +
-  nowTime.getDate();
+let nowTime = dayjs()
+            .subtract(1, "day")
+            .format("YYYY-MM-DD")
 export const getTimes = (times, keys = []) => {
   if (times && times.length) {
     return {
@@ -186,17 +187,24 @@ export default {
   data() {
     return {
       searchForm: {
-        dates: []
+        dates: [
+        dayjs()
+            .subtract(1, "day")
+            .format("YYYY-MM-DD"),
+          dayjs()
+            .subtract(1, "day")
+            .format("YYYY-MM-DD")
+        ]
       },
       tableList: [],
       activeName: "first"
     };
   },
   async mounted() {
-    if (this.searchForm.dates?.length <= 0) {
-      this.searchForm.dates.push(nowTime);
-      this.searchForm.dates.push(nowTime);
-    }
+    // if (this.searchForm.dates?.length <= 0) {
+    //   this.searchForm.dates.push(nowTime);
+    //   this.searchForm.dates.push(nowTime);
+    // }
 
     this.getList();
   },
@@ -242,8 +250,8 @@ export default {
         page: 1
       };
       this.$refs.searchForm.resetFields();
-      this.searchForm.dates.push(getNowDateAndMonday(nowTime));
-      this.searchForm.dates.push(getNowDateAndSunday(nowTime));
+      // this.searchForm.dates.push(getNowDateAndMonday(nowTime));
+      // this.searchForm.dates.push(getNowDateAndSunday(nowTime));
       this.getList();
     },
     getDefaultTime() {
@@ -361,10 +369,11 @@ export default {
     chartData() {
       const temp = {
         normalNum: "会员人数",
-        train1: "<60分钟",
+        train0: "≤10分钟",
+        train1: "10~60分钟",
         train2: "60-120分钟",
         train3: "120-240分钟",
-        train4: ">=240分钟",
+        train4: "240分钟",
         avgTrainTime: "平均时长"
       };
       const values = this.tableList;
@@ -385,7 +394,8 @@ export default {
         columns: [
           "分部",
           "会员人数",
-          "<60分钟",
+          "≤10分钟",
+          "10~60分钟",
           "60-120分钟",
           "120-240分钟",
           ">=240分钟",

+ 9 - 2
src/views/main/cloudDate/exerciseDurationDetail.vue

@@ -97,13 +97,20 @@
               <div>{{ scope.row.trainRate }}%</div>
             </template>
           </el-table-column>
-          <el-table-column align="center" prop="id" label="<60分钟">
+
+          <el-table-column align="center" label="≤10分钟">
+            <template slot-scope="scope">
+              <div>{{ scope.row.train0 }}人</div>
+            </template>
+          </el-table-column>
+
+          <el-table-column align="center" label="10~60分钟">
             <template slot-scope="scope">
               <div>{{ scope.row.train1 }}人</div>
             </template></el-table-column
           >
 
-          <el-table-column align="center" prop="id" label="60~120分钟">
+          <el-table-column align="center" label="60~120分钟">
             <template slot-scope="scope">
               <div>{{ scope.row.train2 }}人</div>
             </template>