Browse Source

Merge branch 'develop' into Psycho/feature-xkw

CrazyIter_Bin 3 năm trước cách đây
mục cha
commit
05ac0ff5d2
42 tập tin đã thay đổi với 4534 bổ sung4050 xóa
  1. 1 1
      TEAMModelBI/ClientApp/public/index.html
  2. BIN
      TEAMModelBI/ClientApp/src/assets/img/school-bg-1.png
  3. BIN
      TEAMModelBI/ClientApp/src/assets/img/school-bg-2.png
  4. BIN
      TEAMModelBI/ClientApp/src/assets/img/school-bg-3.png
  5. 1 1
      TEAMModelBI/ClientApp/src/until/http.js
  6. 211 211
      TEAMModelBI/ClientApp/src/view/bindPhone.vue
  7. 100 100
      TEAMModelBI/ClientApp/src/view/ddlogin.vue
  8. 1 1
      TEAMModelBI/ClientApp/src/view/index/index.vue
  9. 247 247
      TEAMModelBI/ClientApp/src/view/login.vue
  10. 777 785
      TEAMModelBI/ClientApp/src/view/participation/index.vue
  11. 1317 1302
      TEAMModelBI/ClientApp/src/view/participation/setAbility.vue
  12. 46 2
      TEAMModelBI/ClientApp/src/view/schoolServe/school.vue
  13. 1077 832
      TEAMModelBI/ClientApp/src/view/schoolmanage/schoolAnalyse.vue
  14. 3 3
      TEAMModelBI/ClientApp/src/view/systemConfig/operate.vue
  15. 1 1
      TEAMModelBI/ClientApp/src/view/teachermanage/traitmanage.vue
  16. 53 1
      TEAMModelBI/Controllers/BIHome/AnalyseFileController.cs
  17. 21 5
      TEAMModelBI/Controllers/BISchool/BatchAreaController.cs
  18. 122 113
      TEAMModelBI/Controllers/BISchool/BatchSchoolController.cs
  19. 3 0
      TEAMModelBI/Startup.cs
  20. 10 1
      TEAMModelBI/Tool/Context/BIConst.cs
  21. 6 1
      TEAMModelBI/appsettings.Development.json
  22. 6 0
      TEAMModelBI/appsettings.json
  23. 8 5
      TEAMModelOS.FunctionV4/HttpTrigger/IESHttpTrigger.cs
  24. BIN
      TEAMModelOS.FunctionV4/libwkhtmltox.dll
  25. 12 5
      TEAMModelOS.SDK/Models/Cosmos/Common/StudentScoreRecord.cs
  26. 49 30
      TEAMModelOS.SDK/Models/Service/LessonService.cs
  27. 138 135
      TEAMModelOS/ClientApp/public/lang/en-US.js
  28. 88 85
      TEAMModelOS/ClientApp/public/lang/zh-CN.js
  29. 109 106
      TEAMModelOS/ClientApp/public/lang/zh-TW.js
  30. 8 8
      TEAMModelOS/ClientApp/src/utils/editorLangTw.js
  31. 4 4
      TEAMModelOS/ClientApp/src/view/ability/Review.vue
  32. 23 18
      TEAMModelOS/ClientApp/src/view/auth/Product.vue
  33. 3 3
      TEAMModelOS/ClientApp/src/view/classmgt/CreateNotice.vue
  34. 15 9
      TEAMModelOS/ClientApp/src/view/classrecord/eventchart/Exam.vue
  35. 1 1
      TEAMModelOS/ClientApp/src/view/classrecord/eventchart/ExamTable.vue
  36. 3 0
      TEAMModelOS/ClientApp/src/view/homepage/HomePage.vue
  37. 2 1
      TEAMModelOS/ClientApp/src/view/homepage/RcdPoster.vue
  38. 13 5
      TEAMModelOS/ClientApp/src/view/mycourse/MyCourse.vue
  39. 2 2
      TEAMModelOS/ClientApp/src/view/mycourse/notice/Create.vue
  40. 50 22
      TEAMModelOS/ClientApp/src/view/mycourse/student/Student.vue
  41. 2 2
      TEAMModelOS/ClientApp/src/view/notify/CreateNotify.vue
  42. 1 2
      TEAMModelOS/TEAMModelOS.csproj

+ 1 - 1
TEAMModelBI/ClientApp/public/index.html

@@ -11,7 +11,7 @@
     </title>
 </head>
 <script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script>
-<script src="https://at.alicdn.com/t/font_2934132_xd5xs04ekk.js"></script>
+<script src="https://at.alicdn.com/t/font_2934132_6ijxqwuahzj.js"></script>
 
 <body>
     <noscript>

BIN
TEAMModelBI/ClientApp/src/assets/img/school-bg-1.png


BIN
TEAMModelBI/ClientApp/src/assets/img/school-bg-2.png


BIN
TEAMModelBI/ClientApp/src/assets/img/school-bg-3.png


+ 1 - 1
TEAMModelBI/ClientApp/src/until/http.js

@@ -15,7 +15,7 @@ axios.interceptors.request.use(
             config.url.indexOf('tabledd') != -1 || config.url.indexOf('schoolroom') != -1 || config.url.indexOf('syscfg') != -1 || config.url.indexOf('biservers') != -1) {
             config.headers = {
                 'Content-Type': 'application/json',
-                'x-auth-authtoken': JSON.parse(localStorage.id_token)
+                'x-auth-authtoken': JSON.parse(localStorage.id_token),
             }
         } else {
             config.headers = {

+ 211 - 211
TEAMModelBI/ClientApp/src/view/bindPhone.vue

@@ -1,35 +1,35 @@
 <template>
-    <el-dialog v-model="centerDialogVisible" :title="$t(`bind.title`)" width="30%" center :close-on-click-modal="false" :close-on-press-escape="false">
-        <div class="bindbox">
-            <div class="bind-phone">
-                <el-input v-model="phoneData.to" :placeholder="$t(`bind.phoneHint`)" class="input-with-select">
-                    <template #prepend>
-                        <el-select v-model="select" :placeholder="$t(`bind.areaNum`)" style="width: 90px">
-                            <el-option label="86" value="1" />
-                            <el-option label="886" value="2" />
-                        </el-select>
-                    </template>
-                </el-input>
-            </div>
-            <div class="bind-code">
-                <div class="codenum">
-                    <el-row :gutter="20">
-                        <el-input v-model="phonenum.code" placeholder="" />
-                    </el-row>
-                </div>
-                <div class="sendcode">
-                    <el-button type="primary" v-show="showCode.status" @click="getCode()">{{$t(`bind.codes`)}}</el-button>
-                    <el-button type="primary" disabled v-show="showCode.status ==false">{{showCode.count}}秒</el-button>
-                </div>
-            </div>
+  <el-dialog v-model="centerDialogVisible" :title="$t(`bind.title`)" width="30%" center :close-on-click-modal="false" :close-on-press-escape="false">
+    <div class="bindbox">
+      <div class="bind-phone">
+        <el-input v-model="phoneData.to" :placeholder="$t(`bind.phoneHint`)" class="input-with-select">
+          <template #prepend>
+            <el-select v-model="select" :placeholder="$t(`bind.areaNum`)" style="width: 90px">
+              <el-option label="86" value="1" />
+              <el-option label="886" value="2" />
+            </el-select>
+          </template>
+        </el-input>
+      </div>
+      <div class="bind-code">
+        <div class="codenum">
+          <el-row :gutter="20">
+            <el-input v-model="phonenum.code" placeholder="" />
+          </el-row>
         </div>
-        <template #footer>
-            <span class="dialog-footer">
-                <el-button type="primary" @click="bindUser(proxy)">{{$t(`bind.binds`)}}</el-button>
-                <el-button @click="close">取消</el-button>
-            </span>
-        </template>
-    </el-dialog>
+        <div class="sendcode">
+          <el-button type="primary" v-show="showCode.status" @click="getCode()">{{$t(`bind.codes`)}}</el-button>
+          <el-button type="primary" disabled v-show="showCode.status ==false">{{showCode.count}}秒</el-button>
+        </div>
+      </div>
+    </div>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button type="primary" @click="bindUser(proxy)">{{$t(`bind.binds`)}}</el-button>
+        <el-button @click="close">取消</el-button>
+      </span>
+    </template>
+  </el-dialog>
 </template>
 <script>
 import { reactive, ref, getCurrentInstance, watch } from 'vue'
@@ -38,209 +38,209 @@ import { ElMessage } from 'element-plus'
 import { useRouter } from 'vue-router'
 import { useStore } from 'vuex'
 export default {
-    props: {
-        callbackStatus: {
-            type: Object,
-            default: () => {},
-        },
-    },
-    setup(props, content) {
-        console.log(props.callbackStatus, '8888888888888')
-        let { proxy } = getCurrentInstance()
-        let store = useStore()
-        console.log(store.state.binDingstatus)
-        let centerDialogVisible = ref(true)
-        let phonenum = reactive({
-            phone: '',
-            code: '',
-            partitionKey: '',
-            rowKey: '',
-        })
-        //验证冷却
-        let showCode = reactive({
-            status: true,
-            count: '',
-            timer: null,
-        })
-        var phoneData = ref({
-            to: phonenum.phone,
-            lang: 'zh-cn',
-            country: '86',
-        })
-        let phoneName = ref('')
-        var { phoneCode } = pin(proxy)
-        let select = ref('')
-        phonenum.phone = props.callbackStatus.phoneNum
-        phonenum.partitionKey = props.callbackStatus.partitionKey
-        phonenum.rowKey = props.callbackStatus.rowKey
-        //绑定信息
-        phoneData.value.to = props.callbackStatus.phoneNum
-        phoneData.value.country = props.callbackStatus.country
-        phoneData.value.lang = props.callbackStatus.country === '86' || props.callbackStatus.country === null ? 'zh-CN' : 'zh-TW'
-        select = props.callbackStatus.country == '86' || props.callbackStatus.country === null ? '1' : '2'
-        phoneName = props.callbackStatus.name
-        //路由
-        const router = useRouter()
-        //关闭弹窗
-        function close() {
-            centerDialogVisible.value = false
-            store.commit('BindStatus', false)
-        }
-        //监听状态值
-        watch(
-            () => store.state.binDingstatus,
-            (a) => {
-                store.state.binDingstatus = a
-                centerDialogVisible.value = a
-            }
-        )
-        //验证码冷却及发送验证码
-        function getCode() {
-            //验证码冷却部分
-            const TIME_COUNT = 60
-            if (!showCode.timer) {
-                showCode.count = TIME_COUNT
-                showCode.status = false
-                showCode.timer = setInterval(() => {
-                    if (showCode.count > 0 && showCode.count <= TIME_COUNT) {
-                        showCode.count--
-                    } else {
-                        showCode.status = true
-                        clearInterval(showCode.timer)
-                        showCode.timer = null
-                    }
-                }, 1000)
-            }
-            //请求接口
-            phoneCode(phoneData)
-        }
-        //手机号码绑定流程
-        function bindUser(proxy) {
-            let countryPhone = '+' + phoneData.value.country + '-' + phoneData.value.to
-            let randNum = proxy.$access.rand(1000, 9999).toString()
-            console.log(randNum, '随机数')
-            let data = {
-                grant_type: 'create',
-                client_id: '73266ca3-62b1-4304-b837-c672a8c88001',
-                account: countryPhone,
-                name: phoneName,
-                pin_code: phonenum.code,
-                nonce: randNum,
-            }
-            //验证手机号和验证码
-            proxy.$api.verifyCode(data).then((res) => {
-                console.log(res, '验证手机号和验证码')
-                let data
-                if (res.hasOwnProperty('error') && res.error === 3) {
-                    ElMessage.error(proxy.$t(`bind.codeError`))
-                    return
-                }
-                res.hasOwnProperty('error') && res.error === 2 ? (data = { mobile: phoneData.value.to, partitionKey: phonenum.partitionKey, rowKey: phonenum.rowKey }) : ''
-                res.hasOwnProperty('id_token') && res.id_token ? (data = { id_token: res.id_token, loginData: res, partitionKey: phonenum.partitionKey, rowKey: phonenum.rowKey }) : ''
-                bindId(data, proxy)
-            })
-        }
-        //绑定操作
-        function bindId(paramData, proxy) {
-            proxy.$api.bindUserid(paramData).then((res) => {
-                console.log(res, '返回的结果')
-                let blobInfos = { osblob_uri: res.osblob_uri, osblob_sas: res.osblob_sas }
-                res.state === 200
-                    ? (ElMessage.success(proxy.$t(`bind.bindSuccess`)),
-                      localStorage.setItem('userData', JSON.stringify(res.ddUserInfos[0])),
-                      localStorage.setItem('id_token', JSON.stringify(res.id_token)),
-                      localStorage.setItem('blobInfo', JSON.stringify(blobInfos)),
-                      getOrganization(),
-                      Allpermission(),
-                      router.push({ path: '/dashboard' }))
-                    : res.state === 400
-                    ? ElMessage.error(proxy.$t(`commonMsg.parameterError`))
-                    : res.state === 404
-                    ? ElMessage.error(proxy.$t(`bind.notFounddatas`))
-                    : ''
-            })
-        }
-        //获取组织架构
-        function getOrganization() {
-            console.log(proxy, '检查proxy')
-            proxy.$api.getorganization().then((res) => {
-                console.log(res, '组织架构返回的内容')
-                res.state === 200 ? (store.commit('ChangOrganization', res.deptlist), localStorage.setItem('organization', JSON.stringify(res.deptlist))) : ''
-            })
-        }
-        //获取所有权限表
-        function Allpermission() {
-            proxy.$api.getAllpermission().then((res) => {
-                console.log(res, '权限列表')
-                res.authorityBIList ? (store.commit('getPermission', res.authorityBIList), localStorage.setItem('management', JSON.stringify(res.authorityBIList))) : []
-            })
-        }
-        return {
-            store,
-            proxy,
-            centerDialogVisible,
-            phonenum,
-            showCode,
-            getCode,
-            phoneCode,
-            phoneData,
-            bindUser,
-            bindId,
-            close,
-            getOrganization,
-            Allpermission,
-            select,
-            phoneName,
-        }
+  props: {
+    callbackStatus: {
+      type: Object,
+      default: () => { },
     },
-}
-//发送验证码API
-function pin(proxy) {
-    let phoneCode = (datas) => {
-        console.log(datas, '验证码准备发送的参数')
-        let parameter = {
-            to: datas.value.to,
-            lang: datas.value.lang,
-            country: datas.value.country,
+  },
+  setup (props, content) {
+    console.log(props.callbackStatus, '8888888888888')
+    let { proxy } = getCurrentInstance()
+    let store = useStore()
+    console.log(store.state.binDingstatus)
+    let centerDialogVisible = ref(true)
+    let phonenum = reactive({
+      phone: '',
+      code: '',
+      partitionKey: '',
+      rowKey: '',
+    })
+    //验证冷却
+    let showCode = reactive({
+      status: true,
+      count: '',
+      timer: null,
+    })
+    var phoneData = ref({
+      to: phonenum.phone,
+      lang: 'zh-cn',
+      country: '86',
+    })
+    let phoneName = ref('')
+    var { phoneCode } = pin(proxy)
+    let select = ref('')
+    phonenum.phone = props.callbackStatus.phoneNum
+    phonenum.partitionKey = props.callbackStatus.partitionKey
+    phonenum.rowKey = props.callbackStatus.rowKey
+    //绑定信息
+    phoneData.value.to = props.callbackStatus.phoneNum
+    phoneData.value.country = props.callbackStatus.country
+    phoneData.value.lang = props.callbackStatus.country === '86' || props.callbackStatus.country === null ? 'zh-CN' : 'zh-TW'
+    select = props.callbackStatus.country == '86' || props.callbackStatus.country === null ? '1' : '2'
+    phoneName = props.callbackStatus.name
+    //路由
+    const router = useRouter()
+    //关闭弹窗
+    function close () {
+      centerDialogVisible.value = false
+      store.commit('BindStatus', false)
+    }
+    //监听状态值
+    watch(
+      () => store.state.binDingstatus,
+      (a) => {
+        store.state.binDingstatus = a
+        centerDialogVisible.value = a
+      }
+    )
+    //验证码冷却及发送验证码
+    function getCode () {
+      //验证码冷却部分
+      const TIME_COUNT = 60
+      if (!showCode.timer) {
+        showCode.count = TIME_COUNT
+        showCode.status = false
+        showCode.timer = setInterval(() => {
+          if (showCode.count > 0 && showCode.count <= TIME_COUNT) {
+            showCode.count--
+          } else {
+            showCode.status = true
+            clearInterval(showCode.timer)
+            showCode.timer = null
+          }
+        }, 1000)
+      }
+      //请求接口
+      phoneCode(phoneData)
+    }
+    //手机号码绑定流程
+    function bindUser (proxy) {
+      let countryPhone = '+' + phoneData.value.country + '-' + phoneData.value.to
+      let randNum = proxy.$access.rand(1000, 9999).toString()
+      console.log(randNum, '随机数')
+      let data = {
+        grant_type: 'create',
+        client_id: '73266ca3-62b1-4304-b837-c672a8c88001',
+        account: countryPhone,
+        name: phoneName,
+        pin_code: phonenum.code,
+        nonce: randNum,
+      }
+      //验证手机号和验证码
+      proxy.$api.verifyCode(data).then((res) => {
+        console.log(res, '验证手机号和验证码')
+        let data
+        if (res.hasOwnProperty('error') && res.error === 3) {
+          ElMessage.error(proxy.$t(`bind.codeError`))
+          return
         }
-        let { codesInfo } = proxy.$api.Phonepin(parameter).then((res) => {
-            console.log(res, '接口返回')
-            ElMessage.success('发送成功!')
-        })
+        res.hasOwnProperty('error') && res.error === 2 ? (data = { mobile: phoneData.value.to, partitionKey: phonenum.partitionKey, rowKey: phonenum.rowKey }) : ''
+        res.hasOwnProperty('id_token') && res.id_token ? (data = { id_token: res.id_token, loginData: res, partitionKey: phonenum.partitionKey, rowKey: phonenum.rowKey }) : ''
+        bindId(data, proxy)
+      })
+    }
+    //绑定操作
+    function bindId (paramData, proxy) {
+      proxy.$api.bindUserid(paramData).then((res) => {
+        console.log(res, '返回的结果')
+        let blobInfos = { osblob_uri: res.osblob_uri, osblob_sas: res.osblob_sas }
+        res.state === 200
+          ? (ElMessage.success(proxy.$t(`bind.bindSuccess`)),
+            localStorage.setItem('userData', JSON.stringify(res.ddUserInfos[0])),
+            localStorage.setItem('id_token', JSON.stringify(res.id_token)),
+            localStorage.setItem('blobInfo', JSON.stringify(blobInfos)),
+            getOrganization(),
+            Allpermission(),
+            router.push({ path: '/dashboard' }))
+          : res.state === 400
+            ? ElMessage.error(proxy.$t(`commonMsg.parameterError`))
+            : res.state === 404
+              ? ElMessage.error(proxy.$t(`bind.notFounddatas`))
+              : ''
+      })
+    }
+    //获取组织架构
+    function getOrganization () {
+      console.log(proxy, '检查proxy')
+      proxy.$api.getorganization().then((res) => {
+        console.log(res, '组织架构返回的内容')
+        res.state === 200 ? (store.commit('ChangOrganization', res.deptlist), localStorage.setItem('organization', JSON.stringify(res.deptlist))) : ''
+      })
+    }
+    //获取所有权限表
+    function Allpermission () {
+      proxy.$api.getAllpermission().then((res) => {
+        console.log(res, '权限列表')
+        res.authorityBIList ? (store.commit('getPermission', res.authorityBIList), localStorage.setItem('management', JSON.stringify(res.authorityBIList))) : []
+      })
     }
     return {
-        phoneCode,
+      store,
+      proxy,
+      centerDialogVisible,
+      phonenum,
+      showCode,
+      getCode,
+      phoneCode,
+      phoneData,
+      bindUser,
+      bindId,
+      close,
+      getOrganization,
+      Allpermission,
+      select,
+      phoneName,
+    }
+  },
+}
+//发送验证码API
+function pin (proxy) {
+  let phoneCode = (datas) => {
+    console.log(datas, '验证码准备发送的参数')
+    let parameter = {
+      to: datas.value.to,
+      lang: datas.value.lang,
+      country: datas.value.country,
     }
+    let { codesInfo } = proxy.$api.Phonepin(parameter).then((res) => {
+      console.log(res, '接口返回')
+      ElMessage.success('发送成功!')
+    })
+  }
+  return {
+    phoneCode,
+  }
 }
 </script>
 <style scoped>
 .bindbox {
-    width: 55%;
-    height: auto;
-    margin: 0 auto;
+  width: 55%;
+  height: auto;
+  margin: 0 auto;
 }
 .bind-code {
-    margin: 10% 0% 20% 0%;
+  margin: 10% 0% 20% 0%;
 }
 .codenum {
-    float: left;
-    font-size: 18px;
-    width: 60%;
+  float: left;
+  font-size: 18px;
+  width: 60%;
 }
 .sendcode {
-    float: left;
-    width: 33%;
-    margin-left: 7%;
+  float: left;
+  width: 33%;
+  margin-left: 7%;
 }
 </style>
 <style>
 .sendcode button span {
-    font-size: 14px;
+  font-size: 14px;
 }
 .bind-phone .el-select .el-input__inner {
-    padding-right: 20px;
+  padding-right: 20px;
 }
 .bind-code .el-row {
-    margin-left: 0px !important;
+  margin-left: 0px !important;
 }
 </style>

+ 100 - 100
TEAMModelBI/ClientApp/src/view/ddlogin.vue

@@ -1,119 +1,119 @@
 <template>
-    <div style="width:100%">
-        <div id="login_container" style="margin-bottom:5%;"></div>
-    </div>
+  <div style="width:100%">
+    <div id="login_container" style="margin-bottom:5%;"></div>
+  </div>
 </template>
  
 <script>
 const hosts = window.location.host === 'localhost:5001' ? 'localhost:5001' : 'bitest.teammodel.cn'
 import axios from 'axios'
 export default {
-    name: 'App',
-    components: {},
-    data() {
-        return {
-            appid: 'dingrucgsnt8p13rfbgd',
-            redirectUrl: 'https://' + hosts + '/login',
-            // apiUrl: '/common/login/DingLogin',
-            dingCodeConfig: {
-                id: 'login_container',
-                style: 'background-color:#FFFFFF;',
-                width: '300',
-                height: '350',
-            },
-        }
+  name: 'App',
+  components: {},
+  data () {
+    return {
+      appid: 'dingrucgsnt8p13rfbgd',
+      redirectUrl: 'https://' + hosts + '/login',
+      // apiUrl: '/common/login/DingLogin',
+      dingCodeConfig: {
+        id: 'login_container',
+        style: 'background-color:#FFFFFF;',
+        width: '300',
+        height: '350',
+      },
+    }
+  },
+  computed: {
+    getRedirectUrl () {
+      return encodeURIComponent(this.redirectUrl)
+    },
+    getAuthUrl () {
+      return `https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=${this.appid}&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=${this.getRedirectUrl}`
     },
-    computed: {
-        getRedirectUrl() {
-            return encodeURIComponent(this.redirectUrl)
-        },
-        getAuthUrl() {
-            return `https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=${this.appid}&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=${this.getRedirectUrl}`
-        },
-        getGoto() {
-            return encodeURIComponent(this.getAuthUrl)
-        },
-        getDingCodeConfig() {
-            return { ...this.dingCodeConfig, goto: this.getGoto }
-        },
+    getGoto () {
+      return encodeURIComponent(this.getAuthUrl)
     },
-    created() {
-        this.initDingJs()
+    getDingCodeConfig () {
+      return { ...this.dingCodeConfig, goto: this.getGoto }
     },
-    mounted() {
-        this.addDingListener()
-        this.initDingLogin()
-        this.getUser()
+  },
+  created () {
+    this.initDingJs()
+  },
+  mounted () {
+    this.addDingListener()
+    this.initDingLogin()
+    this.getUser()
+  },
+  methods: {
+    initDingJs () {
+      console.log('触发方法')
+      !(function (window, document) {
+        function d (a) {
+          var e,
+            c = document.createElement('iframe'),
+            d = 'https://login.dingtalk.com/login/qrcode.htm?goto=' + a.goto
+            ; (d += a.style ? '&style=' + encodeURIComponent(a.style) : ''),
+              (d += a.href ? '&href=' + a.href : ''),
+              (c.src = d),
+              (c.frameBorder = '0'),
+              (c.allowTransparency = 'true'),
+              (c.scrolling = 'no'),
+              (c.width = a.width ? a.width + 'px' : '365px'),
+              (c.height = a.height ? a.height + 'px' : '400px'),
+              (e = document.getElementById(a.id)),
+              (e.innerHTML = ''),
+              e.appendChild(c)
+        }
+        console.log(d)
+        window.DDLogin = d
+      })(window, document)
     },
-    methods: {
-        initDingJs() {
-            console.log('触发方法')
-            !(function (window, document) {
-                function d(a) {
-                    var e,
-                        c = document.createElement('iframe'),
-                        d = 'https://login.dingtalk.com/login/qrcode.htm?goto=' + a.goto
-                    ;(d += a.style ? '&style=' + encodeURIComponent(a.style) : ''),
-                        (d += a.href ? '&href=' + a.href : ''),
-                        (c.src = d),
-                        (c.frameBorder = '0'),
-                        (c.allowTransparency = 'true'),
-                        (c.scrolling = 'no'),
-                        (c.width = a.width ? a.width + 'px' : '365px'),
-                        (c.height = a.height ? a.height + 'px' : '400px'),
-                        (e = document.getElementById(a.id)),
-                        (e.innerHTML = ''),
-                        e.appendChild(c)
-                }
-                console.log(d)
-                window.DDLogin = d
-            })(window, document)
-        },
-        addDingListener() {
-            let self = this
+    addDingListener () {
+      let self = this
 
-            let handleLoginTmpCode = function (loginTmpCode) {
-                window.location.href = self.getAuthUrl + `&loginTmpCode=${loginTmpCode}`
-            }
+      let handleLoginTmpCode = function (loginTmpCode) {
+        window.location.href = self.getAuthUrl + `&loginTmpCode=${loginTmpCode}`
+      }
 
-            let handleMessage = function (event) {
-                if (event.origin == 'https://login.dingtalk.com') {
-                    handleLoginTmpCode(event.data)
-                }
-            }
+      let handleMessage = function (event) {
+        if (event.origin == 'https://login.dingtalk.com') {
+          handleLoginTmpCode(event.data)
+        }
+      }
 
-            if (typeof window.addEventListener != 'undefined') {
-                window.addEventListener('message', handleMessage, false)
-            } else if (typeof window.attachEvent != 'undefined') {
-                window.attachEvent('onmessage', handleMessage)
-            }
-        },
-        initDingLogin() {
-            window.DDLogin(this.getDingCodeConfig)
-        },
-        getUser() {
-            let getQueryString = function (name) {
-                var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
-                var r = window.location.search.substr(1).match(reg)
-                if (r != null) {
-                    return unescape(r[2])
-                }
-                return null
-            }
+      if (typeof window.addEventListener != 'undefined') {
+        window.addEventListener('message', handleMessage, false)
+      } else if (typeof window.attachEvent != 'undefined') {
+        window.attachEvent('onmessage', handleMessage)
+      }
+    },
+    initDingLogin () {
+      window.DDLogin(this.getDingCodeConfig)
+    },
+    getUser () {
+      let getQueryString = function (name) {
+        var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
+        var r = window.location.search.substr(1).match(reg)
+        if (r != null) {
+          return unescape(r[2])
+        }
+        return null
+      }
 
-            let code = getQueryString('code')
+      let code = getQueryString('code')
 
-            if (code !== null) {
-                axios
-                    .get(`${this.apiUrl}?code=${code}`)
-                    .then((response) => {
-                        console.log(response)
-                    })
-                    .catch((error) => {
-                        console.log(error)
-                    })
-            }
-        },
+      if (code !== null) {
+        axios
+          .get(`${this.apiUrl}?code=${code}`)
+          .then((response) => {
+            console.log(response)
+          })
+          .catch((error) => {
+            console.log(error)
+          })
+      }
     },
+  },
 }
 </script>

+ 1 - 1
TEAMModelBI/ClientApp/src/view/index/index.vue

@@ -1629,7 +1629,7 @@ export default {
               console.log(res, '处理过后的时间')
               for (let i in replaceTime) {
                 let nums = parseInt(i) + 1
-                replaceTime[i].value == onlineData[onlineData.length - 1].key ? replaceTime.splice(nums) : ''
+                replaceTime[i].value == hoursInfo ? replaceTime.splice(nums) : ''
               }
               //在线人数趋势
               onlineData.forEach((x) => {

+ 247 - 247
TEAMModelBI/ClientApp/src/view/login.vue

@@ -1,8 +1,8 @@
 <template>
-    <div class="backgorundbox">
-        <div class="loginbox">
-            <div class="logintitle">{{ $t(`login.title`) }}</div>
-            <!-- <div class="usrpwd" v-if="loginModel">
+  <div class="backgorundbox">
+    <div class="loginbox">
+      <div class="logintitle">{{ $t(`login.title`) }}</div>
+      <!-- <div class="usrpwd" v-if="loginModel">
                 <div class='userbox' style="margin-bottom:10%">
                     <el-input v-model="user" placeholder="醍摩豆ID/手机号码" prefix-icon="el-icon-user" />
                 </div>
@@ -15,10 +15,10 @@
                     <div class="ddlogin" @click="loginModel=false"><img src="../assets/img/ddlogin.png"></div>
                 </div>
             </div> -->
-            <div class="usrpwd">
-                <ddlogin></ddlogin>
-            </div>
-            <!-- <div class="cut" @click="loginModel = !loginModel">
+      <div class="usrpwd">
+        <ddlogin></ddlogin>
+      </div>
+      <!-- <div class="cut" @click="loginModel = !loginModel">
                 <svg width="52" height="52" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" style="border-top-right-radius:10px">
                     <mask id="id-3757926926-a" width="52" height="52" x="0" y="0" maskUnits="userSpaceOnUse">
                         <path fill="#fff" d="M0 0l52 52V0H0z"></path>
@@ -35,12 +35,12 @@
                     </defs>
                 </svg>
             </div> -->
-        </div>
-        <!-- <div id="login_container" style="transform: scale(.8);">123456</div> -->
-        <!--绑定弹窗-->
-        <!-- <bind :callbackStatus=callbackStatus v-if="callbackStatus.state ===201" ref="comRef"></bind> -->
-        <!--绑定弹窗end-->
     </div>
+    <!-- <div id="login_container" style="transform: scale(.8);">123456</div> -->
+    <!--绑定弹窗-->
+    <!-- <bind :callbackStatus=callbackStatus v-if="callbackStatus.state ===201" ref="comRef"></bind> -->
+    <!--绑定弹窗end-->
+  </div>
 </template>
 <script>
 import { ref, watch, onMounted, getCurrentInstance, toRef, reactive } from 'vue'
@@ -51,293 +51,293 @@ import { useRouter } from 'vue-router'
 import { useStore } from 'vuex'
 import jwt_decode from 'jwt-decode'
 export default {
-    components: {
-        ddlogin,
-        bind,
-    },
-    setup() {
-        var types = navigator.language
-        localStorage.setItem('language', JSON.stringify(types))
-        let user = ref('')
-        let pwd = ref('')
-        let loginModel = ref(true)
-        let loginImg = ref(require('../assets/img/erweima.png'))
-        var userCode = ''
-        let callbackStatus = ref({
-            state: '',
-            phoneNum: '',
-            partitionKey: '',
-            rowKey: '',
-            country: '',
-            name: '',
+  components: {
+    ddlogin,
+    bind,
+  },
+  setup () {
+    var types = navigator.language
+    localStorage.setItem('language', JSON.stringify(types))
+    let user = ref('')
+    let pwd = ref('')
+    let loginModel = ref(true)
+    let loginImg = ref(require('../assets/img/erweima.png'))
+    var userCode = ''
+    let callbackStatus = ref({
+      state: '',
+      phoneNum: '',
+      partitionKey: '',
+      rowKey: '',
+      country: '',
+      name: '',
+    })
+    let router = useRouter()
+    let { proxy } = getCurrentInstance()
+    const store = useStore()
+    console.log(store, 'VUEX')
+    let comRef = ref(null)
+    let loading = reactive({
+      lock: '',
+      text: '',
+      background: '',
+    })
+    let loadings = ref(true)
+    let msgText = ref('钉钉扫码登录')
+    onMounted(() => {
+      if (window.location.href.indexOf('?code') != -1) {
+        userCode = window.location.href.substring(window.location.href.indexOf('?') + 6, window.location.href.indexOf('&state'))
+        console.log(userCode)
+        editState(userCode)
+      }
+      localStorage.setItem('Host', JSON.stringify(window.location.host))
+    })
+    //处理登录icon变化
+    watch(loginModel, () => {
+      loginModel.value == true
+        ? ((loginImg.value = require('../assets/img/erweima.png')), (msgText.value = '钉钉账号登录'))
+        : ((loginImg.value = require('../assets/img/mima.png')), (msgText.value = '钉钉扫码登录'))
+    })
+    let { editState } = test(proxy)
+    function test (proxy) {
+      let editState = (res) => {
+        loading = ElLoading.service({
+          lock: true,
+          text: proxy.$t(`login.logining`),
+          background: 'rgba(0, 0, 0, 0.7)',
         })
-        let router = useRouter()
-        let { proxy } = getCurrentInstance()
-        const store = useStore()
-        console.log(store, 'VUEX')
-        let comRef = ref(null)
-        let loading = reactive({
-            lock: '',
-            text: '',
-            background: '',
+        let datas = { code: res }
+        proxy.$api.Dinglogin(datas).then((res) => {
+          console.log(res, '接口访问成功')
+          callbackStatus.value.state = res.state
+          callbackStatus.value.partitionKey = res.ddUserInfos[0].partitionKey
+          callbackStatus.value.rowKey = res.ddUserInfos[0].rowKey
+          // res.state === 201
+          //     ? (store.commit('BindStatus', true),
+          //       loading.close(),
+          //       (callbackStatus.value.country = res.ddUserInfos[0].stateCode),
+          //       (callbackStatus.value.name = res.ddUserInfos[0].name),
+          //       (callbackStatus.value.phoneNum = res.ddUserInfos[0].mobile))
+          //     : res.state === 200
+          //     ? (loading.close(), loginSuccess(res), ElMessage.success(proxy.$t(`login.loginSuccess`)))
+          //     : (loading.close(), ElMessage.error(res.message))
+          res.state === 200 ? ElMessage.success(proxy.$t(`login.loginSuccess`), loginSuccess(res)) : res.state === 0 ? ElMessage.error(res.msg) : ElMessage.error('登录失败')
+          loading.close()
         })
-        let loadings = ref(true)
-        let msgText = ref('钉钉扫码登录')
-        onMounted(() => {
-            if (window.location.href.indexOf('?code') != -1) {
-                userCode = window.location.href.substring(window.location.href.indexOf('?') + 6, window.location.href.indexOf('&state'))
-                console.log(userCode)
-                editState(userCode)
-            }
-            localStorage.setItem('Host', JSON.stringify(window.location.host))
-        })
-        //处理登录icon变化
-        watch(loginModel, () => {
-            loginModel.value == true
-                ? ((loginImg.value = require('../assets/img/erweima.png')), (msgText.value = '钉钉账号登录'))
-                : ((loginImg.value = require('../assets/img/mima.png')), (msgText.value = '钉钉扫码登录'))
-        })
-        let { editState } = test(proxy)
-        function test(proxy) {
-            let editState = (res) => {
-                loading = ElLoading.service({
-                    lock: true,
-                    text: proxy.$t(`login.logining`),
-                    background: 'rgba(0, 0, 0, 0.7)',
-                })
-                let datas = { code: res }
-                proxy.$api.Dinglogin(datas).then((res) => {
-                    console.log(res, '接口访问成功')
-                    callbackStatus.value.state = res.state
-                    callbackStatus.value.partitionKey = res.ddUserInfos[0].partitionKey
-                    callbackStatus.value.rowKey = res.ddUserInfos[0].rowKey
-                    // res.state === 201
-                    //     ? (store.commit('BindStatus', true),
-                    //       loading.close(),
-                    //       (callbackStatus.value.country = res.ddUserInfos[0].stateCode),
-                    //       (callbackStatus.value.name = res.ddUserInfos[0].name),
-                    //       (callbackStatus.value.phoneNum = res.ddUserInfos[0].mobile))
-                    //     : res.state === 200
-                    //     ? (loading.close(), loginSuccess(res), ElMessage.success(proxy.$t(`login.loginSuccess`)))
-                    //     : (loading.close(), ElMessage.error(res.message))
-                    res.state === 200 ? ElMessage.success(proxy.$t(`login.loginSuccess`), loginSuccess(res)) : res.state === 0 ? ElMessage.error(res.msg) : ElMessage.error('登录失败')
-                    loading.close()
-                })
-            }
-            return {
-                editState,
-            }
-        }
-        //登录成功后执行的数据保存本地
-        function loginSuccess(res) {
-            if (res.state === 200) {
-                let blobInfos = { osblob_uri: res.osblob_uri, osblob_sas: res.osblob_sas }
-                localStorage.setItem('userData', JSON.stringify(res.ddUserInfos[0]))
-                localStorage.setItem('id_token', JSON.stringify(res.id_token))
-                localStorage.setItem('blobInfo', JSON.stringify(blobInfos))
-                getOrganization()
-                Allpermission()
-                router.push('/home/index')
-            }
-        }
-        //获取组织架构
-        function getOrganization() {
-            console.log(proxy, '检查proxy')
-            proxy.$api.getorganization().then((res) => {
-                console.log(res, '组织架构返回的内容')
-                res.state === 200 ? (store.commit('ChangOrganization', res.deptlist), localStorage.setItem('organization', JSON.stringify(res.deptlist))) : ''
-            })
-        }
-        //获取所有权限表
-        function Allpermission() {
-            proxy.$api.getAllpermission().then((res) => {
-                console.log(res, '权限列表')
-                res.authorityBIList ? (store.commit('getPermission', res.authorityBIList), localStorage.setItem('management', JSON.stringify(res.authorityBIList))) : []
-            })
-        }
-        // //钉钉账号或扫码登录
-        // function userlogin(proxy) {
-        //     loading = ElLoading.service({
-        //         lock: true,
-        //         text: 'Loading',
-        //         background: 'rgba(0, 0, 0, 0.7)',
-        //     })
-        //     let nonceNum = Math.floor(Math.random() * 10000)
-        //     console.log(nonceNum, '随机数')
-        //     let params = {
-        //         grant_type: 'account',
-        //         client_id: 'c7317f88-7cea-4e48-ac57-a16071f7b884',
-        //         nonce: 'habook',
-        //         account: user.value,
-        //         password: pwd.value,
-        //     }
-        //     // proxy.$api.loginUser(params).then(async (res) => {
-        //     //     console.log(res, '登录接口返回成功!')
-        //     //     res.error
-        //     //         ? (ElMessage.error('密码错误'), loading.close())
-        //     //         : res.id_token
-        //     //         ? (getTeachinfo(proxy, res.id_token), Allpermission(proxy), getOrganization(proxy))
-        //     //         : (loading.close(), ElMessage.error('登录失败'))
-        //     //     // router.push("/home");
-        //     // })
-        // }
-        // //获取教师个人信息
-        // function getTeachinfo(proxy, param) {
-        //     let parameter = { id_token: param }
-        //     proxy.$api.teacherinfo(parameter).then((res) => {
-        //         if (res.state === 1) {
-        //             ElMessage.warning('该账户未绑定钉钉信息!请扫码绑定信息!')
-        //             loginModel.value = false
-        //         } else {
-        //             localStorage.setItem('userData', JSON.stringify(res))
-        //             console.log(res, '教室个人信息')
-        //             let jwt_authtoken = {
-        //                 jwt_user: jwt_decode(res.auth_token),
-        //             }
-        //             res = Object.assign(res, jwt_authtoken)
-        //             res.state === 200 ? store.commit('getTeachdata', res) : []
-        //             loading.close()
-        //             ElMessage.success('登录成功')
-        //             store.commit('getBlobsas', { host: res.osblob_uri, sas: res.osblob_sas })
-        //             // router.push('/home')
-        //         }
-        //     })
-        // }
-        return {
-            comRef,
-            store,
-            proxy,
-            user,
-            pwd,
-            loginModel,
-            loginImg,
-            userCode,
-            editState,
-            callbackStatus,
-            router,
-            loading,
-            msgText,
-            getOrganization,
-            Allpermission,
-            loginSuccess,
-            loadings,
-        }
-    },
+      }
+      return {
+        editState,
+      }
+    }
+    //登录成功后执行的数据保存本地
+    function loginSuccess (res) {
+      if (res.state === 200) {
+        let blobInfos = { osblob_uri: res.osblob_uri, osblob_sas: res.osblob_sas }
+        localStorage.setItem('userData', JSON.stringify(res.ddUserInfos[0]))
+        localStorage.setItem('id_token', JSON.stringify(res.id_token))
+        localStorage.setItem('blobInfo', JSON.stringify(blobInfos))
+        getOrganization()
+        Allpermission()
+        router.push('/home/index')
+      }
+    }
+    //获取组织架构
+    function getOrganization () {
+      console.log(proxy, '检查proxy')
+      proxy.$api.getorganization().then((res) => {
+        console.log(res, '组织架构返回的内容')
+        res.state === 200 ? (store.commit('ChangOrganization', res.deptlist), localStorage.setItem('organization', JSON.stringify(res.deptlist))) : ''
+      })
+    }
+    //获取所有权限表
+    function Allpermission () {
+      proxy.$api.getAllpermission().then((res) => {
+        console.log(res, '权限列表')
+        res.authorityBIList ? (store.commit('getPermission', res.authorityBIList), localStorage.setItem('management', JSON.stringify(res.authorityBIList))) : []
+      })
+    }
+    // //钉钉账号或扫码登录
+    // function userlogin(proxy) {
+    //     loading = ElLoading.service({
+    //         lock: true,
+    //         text: 'Loading',
+    //         background: 'rgba(0, 0, 0, 0.7)',
+    //     })
+    //     let nonceNum = Math.floor(Math.random() * 10000)
+    //     console.log(nonceNum, '随机数')
+    //     let params = {
+    //         grant_type: 'account',
+    //         client_id: 'c7317f88-7cea-4e48-ac57-a16071f7b884',
+    //         nonce: 'habook',
+    //         account: user.value,
+    //         password: pwd.value,
+    //     }
+    //     // proxy.$api.loginUser(params).then(async (res) => {
+    //     //     console.log(res, '登录接口返回成功!')
+    //     //     res.error
+    //     //         ? (ElMessage.error('密码错误'), loading.close())
+    //     //         : res.id_token
+    //     //         ? (getTeachinfo(proxy, res.id_token), Allpermission(proxy), getOrganization(proxy))
+    //     //         : (loading.close(), ElMessage.error('登录失败'))
+    //     //     // router.push("/home");
+    //     // })
+    // }
+    // //获取教师个人信息
+    // function getTeachinfo(proxy, param) {
+    //     let parameter = { id_token: param }
+    //     proxy.$api.teacherinfo(parameter).then((res) => {
+    //         if (res.state === 1) {
+    //             ElMessage.warning('该账户未绑定钉钉信息!请扫码绑定信息!')
+    //             loginModel.value = false
+    //         } else {
+    //             localStorage.setItem('userData', JSON.stringify(res))
+    //             console.log(res, '教室个人信息')
+    //             let jwt_authtoken = {
+    //                 jwt_user: jwt_decode(res.auth_token),
+    //             }
+    //             res = Object.assign(res, jwt_authtoken)
+    //             res.state === 200 ? store.commit('getTeachdata', res) : []
+    //             loading.close()
+    //             ElMessage.success('登录成功')
+    //             store.commit('getBlobsas', { host: res.osblob_uri, sas: res.osblob_sas })
+    //             // router.push('/home')
+    //         }
+    //     })
+    // }
+    return {
+      comRef,
+      store,
+      proxy,
+      user,
+      pwd,
+      loginModel,
+      loginImg,
+      userCode,
+      editState,
+      callbackStatus,
+      router,
+      loading,
+      msgText,
+      getOrganization,
+      Allpermission,
+      loginSuccess,
+      loadings,
+    }
+  },
 }
 </script>
 <style scoped>
 .backgorundbox {
-    background: url('../assets/img/background1.png') no-repeat;
-    background-size: cover;
-    width: 100vw;
-    height: 100vh;
-    position: relative;
-    /* filter: blur(2px); */
+  background: url("../assets/img/background1.png") no-repeat;
+  background-size: cover;
+  width: 100vw;
+  height: 100vh;
+  position: relative;
+  /* filter: blur(2px); */
 }
 
 .loginbox {
-    position: absolute;
-    width: 550px;
-    height: auto;
-    top: 200px;
-    right: 110px;
-    border-radius: 10px;
-    box-shadow: 1px 1px 5px #ccc;
+  position: absolute;
+  width: 550px;
+  height: auto;
+  top: 200px;
+  right: 110px;
+  border-radius: 10px;
+  box-shadow: 1px 1px 5px #ccc;
 }
 
 .usrpwd {
-    height: 330px;
-    text-align: center;
+  height: 330px;
+  text-align: center;
 }
 
 .logintitle {
-    text-align: center;
-    font-size: 20px;
-    color: #fff;
-    margin-bottom: 8%;
-    margin-top: 5%;
+  text-align: center;
+  font-size: 20px;
+  color: #fff;
+  margin-bottom: 8%;
+  margin-top: 5%;
 }
 
 .userbox {
-    text-align: center;
-    width: 60%;
-    margin: 0 auto;
-    position: relative;
+  text-align: center;
+  width: 60%;
+  margin: 0 auto;
+  position: relative;
 }
 
 .none {
-    display: none;
+  display: none;
 }
 
 .loginbtn {
-    position: absolute;
-    display: block;
-    right: 0px;
-    top: 0px;
-    width: 44px;
-    height: 44px;
-    line-height: 43px;
+  position: absolute;
+  display: block;
+  right: 0px;
+  top: 0px;
+  width: 44px;
+  height: 44px;
+  line-height: 43px;
 }
 
 .not_has_more {
-    margin: 30px 0px 20px 0px;
-    line-height: 50px;
-    text-align: center;
-    position: relative;
-    height: 95px;
-    font-size: 14px;
-    font-family: PingFangSC-Regular, PingFang SC;
-    font-weight: 400;
-    color: rgba(140, 142, 165, 1);
-    line-height: 30px;
+  margin: 30px 0px 20px 0px;
+  line-height: 50px;
+  text-align: center;
+  position: relative;
+  height: 95px;
+  font-size: 14px;
+  font-family: PingFangSC-Regular, PingFang SC;
+  font-weight: 400;
+  color: rgba(140, 142, 165, 1);
+  line-height: 30px;
 }
 
 .not_has_more::after,
 .not_has_more::before {
-    position: absolute;
-    width: 54px;
-    height: 0.5px;
-    background: #dadada;
-    content: '';
-    top: 15px;
-    right: 28%;
+  position: absolute;
+  width: 54px;
+  height: 0.5px;
+  background: #dadada;
+  content: "";
+  top: 15px;
+  right: 28%;
 }
 
 .not_has_more::after {
-    left: 28%;
+  left: 28%;
 }
 
 .ddlogin {
-    margin-top: 3%;
+  margin-top: 3%;
 }
 
 .cut {
-    position: absolute;
-    top: 0px;
-    right: 0px;
+  position: absolute;
+  top: 0px;
+  right: 0px;
 }
 </style>
 <style>
 .userbox .el-input__inner {
-    height: 45px;
-    border-radius: 30px;
+  height: 45px;
+  border-radius: 30px;
 }
 
 .el-loading-spinner {
-    margin-top: 0 !important;
-    transform: translateY(-50%);
+  margin-top: 0 !important;
+  transform: translateY(-50%);
 }
 
 .el-loading-text {
-    padding-top: 50px;
-    background-image: url('../assets/img/loading2.gif') !important;
-    background-repeat: no-repeat;
-    background-position: top center;
-    background-size: 75px auto;
+  padding-top: 50px;
+  background-image: url("../assets/img/loading2.gif") !important;
+  background-repeat: no-repeat;
+  background-position: top center;
+  background-size: 75px auto;
 }
 
 .el-loading-spinner .circular {
-    display: none;
+  display: none;
 }
 </style>
 

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 777 - 785
TEAMModelBI/ClientApp/src/view/participation/index.vue


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1317 - 1302
TEAMModelBI/ClientApp/src/view/participation/setAbility.vue


+ 46 - 2
TEAMModelBI/ClientApp/src/view/schoolServe/school.vue

@@ -62,11 +62,22 @@
                 </el-table-column> -->
         <el-table-column :label="$t(`schoolManages.tables.scale`)" class="school-table-edition" align="center">
           <template #default="scope">
-            <el-image style="width: 80px; height: 80px" :src="imgData.basics" fit="fill" v-if="scope.row.scale === 0"></el-image>
+            <!-- <el-image style="width: 80px; height: 80px" :src="imgData.basics" fit="fill" v-if="scope.row.scale === 0"></el-image>
             <el-image style="width: 80px; height: 80px" :src="imgData.standard" fit="fill" v-else-if="scope.row.scale === 500 && scope.row.hard.length === 0 && scope.row.serial.length === 0 && scope.row.service.length === 0">
             </el-image>
             <el-image style="width: 80px; height: 80px" :src="imgData.specialty" fit="fill" v-else-if="scope.row.scale === 500 && (scope.row.hard.length != 0 || scope.row.serial.length != 0 || scope.row.service.length != 0)">
-            </el-image>
+            </el-image> -->
+            <div class="scalebox">
+              <p class="scalebox-content" v-if="scope.row.scale === 0">
+                基础版
+              </p>
+              <p class="scalebox-content" v-else-if="scope.row.scale === 500 && scope.row.hard.length === 0 && scope.row.serial.length === 0 && scope.row.service.length === 0">
+                标准版
+              </p>
+              <p class="scalebox-content" v-else-if="scope.row.scale === 500 && (scope.row.hard.length != 0 || scope.row.serial.length != 0 || scope.row.service.length != 0)">
+                专业版
+              </p>
+            </div>
           </template>
         </el-table-column>
         <el-table-column prop="id" :label="$t(`schoolManages.tables.brevityCode`)" align="center" />
@@ -970,6 +981,39 @@ export default {
   font-size: 14px;
   color: #636e72;
 }
+.scalebox {
+  width: 100%;
+}
+.scalebox-content {
+  color: #592e02;
+  background: linear-gradient(90deg, #734311, #ffc78c, #734311);
+  text-align: center;
+  padding: 2px 0;
+  font-size: 12px;
+  z-index: 999;
+  position: relative;
+  margin-bottom: 0px;
+}
+.scalebox-content::before {
+  border-top: 6px solid #dca974;
+  bottom: -1px;
+  right: -4px;
+  content: " ";
+  position: absolute;
+  border-right: 6px solid transparent;
+  border-left: 6px solid transparent;
+  transform: rotate(-45deg);
+}
+.scalebox-content:after {
+  content: " ";
+  position: absolute;
+  border-right: 6px solid transparent;
+  border-left: 6px solid transparent;
+  transform: rotate(-45deg);
+  border-bottom: 6px solid #dca974;
+  top: -1px;
+  left: -4px;
+}
 </style>
 <style>
 .schoolboxea .el-cascader {

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1077 - 832
TEAMModelBI/ClientApp/src/view/schoolmanage/schoolAnalyse.vue


+ 3 - 3
TEAMModelBI/ClientApp/src/view/systemConfig/operate.vue

@@ -59,11 +59,11 @@ export default {
     const identityValue = ref([])
     const options = [
       {
-        value: 'channelcrew',
-        label: '渠道人员',
+        value: 'rdc',
+        label: '研发部',
       },
       {
-        value: 'sellcrew',
+        value: 'sales',
         label: '销售',
       },
       {

+ 1 - 1
TEAMModelBI/ClientApp/src/view/teachermanage/traitmanage.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="abilitysInfo">
     <!--外部呈现-->
-    <div class="site-box" v-show="siteCut.show">
+    <div class="site-box" v-show="siteCut.show && treeModel === 'default'">
       <span :class="[siteCut.positionIndex ===1 ? 'site-pitch':'']" @click="cutSite(1,'china')">中国</span>
       <span :class="[siteCut.positionIndex ===2 ? 'site-pitch':'']" @click="cutSite(2,'international')">国际</span>
     </div>

+ 53 - 1
TEAMModelBI/Controllers/BIHome/AnalyseFileController.cs

@@ -11,6 +11,7 @@ using System.Text;
 using System.Text.Json;
 using System.Threading.Tasks;
 using TEAMModelBI.Models.RecordM;
+using TEAMModelBI.Tool.Context;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Models.Cosmos.BI;
@@ -30,6 +31,11 @@ namespace TEAMModelBI.Controllers.BIHome
             _azureStorage = azureStorage;
         }
 
+        /// <summary>
+        /// 本地Json
+        /// </summary>
+        /// <param name="jsonElement"></param>
+        /// <returns></returns>
         [HttpPost("get-visitjson")]
         public async Task<IActionResult> GetVisitJson(JsonElement jsonElement) 
         {
@@ -102,7 +108,53 @@ namespace TEAMModelBI.Controllers.BIHome
             return Ok(new { state = 200, recCnts,  apiCon = apiCnt.Count(), apiSum = apiCnt.Select(ap => ap.count).Sum(), ipCount = ipCnt.Count, ipSum = ipCnt.Select(ip => ip.count).Sum(), ipCnt, apiCnt }); ;
 
             //return Ok(new { state = 200, cnt = recInfo.Count, apiCon = apiCnt.Count(), apiSum = apiCnt.Select(ap=> ap.count).Sum(), ipCount = ipCnt.Count, ipSum = ipCnt.Select(ip=>ip.count).Sum(), ipCnt,apiCnt, recInfo   });;
-        }               
+        }
+
+        /// <summary>
+        /// 日志访问秘钥
+        /// </summary>
+        /// <param name="jsonElement"></param>
+        /// <returns></returns>
+        [HttpPost("get-loginfos")]
+        public async Task<IActionResult> GetOSLog(JsonElement jsonElement) 
+        {
+            jsonElement.TryGetProperty("site", out JsonElement site);
+            DateTimeOffset dateTime = DateTimeOffset.UtcNow;
+            int year = dateTime.Year;
+            int month = dateTime.Month;
+            int day = dateTime.Day;
+            int hour = dateTime.Hour;
+
+            var blobClient = _azureStorage.GetBlobContainerClient($"insights-logs-applicationgatewayfirewalllog",name:BIConst.LogChinaSite);
+            if ($"{site}".Equals(BIConst.LogGlobalSite)) 
+            {
+                blobClient = _azureStorage.GetBlobContainerClient($"insights-logs-applicationgatewayfirewalllog", name: BIConst.LogGlobalSite);
+            }
+            //地址:    y={year}/m={month}/d={day}/h={hour}/m=00/PT1H.json
+            string logName = "resourceId=/SUBSCRIPTIONS/73B7F9EF-D8B7-4444-9E8D-D80B43BF3CD4/RESOURCEGROUPS/TEAMMODELCHENGDU/PROVIDERS/MICROSOFT.NETWORK/APPLICATIONGATEWAYS/OSFIREWARE";
+            await foreach (BlobItem blobItem in blobClient.GetBlobsAsync(BlobTraits.None, BlobStates.None, logName))
+            {
+                BlobClient tempBlobClient = blobClient.GetBlobClient(blobItem.Name);
+
+
+                StreamReader streamReader = new StreamReader(new FileStream(blobItem.Name, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Encoding.UTF8);
+                if (await blobClient.ExistsAsync())
+                {
+                }
+            }
+
+
+
+
+
+
+
+
+
+            return Ok(new { state = 200 });
+        }
+
+
 
         public record StatisNameCnt 
         {

+ 21 - 5
TEAMModelBI/Controllers/BISchool/BatchAreaController.cs

@@ -492,8 +492,16 @@ namespace TEAMModelBI.Controllers.BISchool
                 var messageBatchCopyFile = new ServiceBusMessage(batchCopyFile.ToJsonString());
                 messageBatchCopyFile.ApplicationProperties.Add("name", "CopyStandardFile");
                 //var activeTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
-                //await  _serviceBus.GetServiceBusClient().SendMessageAsync(activeTask, messageBatchCopyFile);
-                await serBusClient.SendMessageAsync(activeTask, messageBatchCopyFile);
+
+                try
+                {
+                    //await  _serviceBus.GetServiceBusClient().SendMessageAsync(activeTask, messageBatchCopyFile);
+                    await serBusClient.SendMessageAsync(activeTask, messageBatchCopyFile);
+                }
+                catch (Exception)
+                {
+                    return Ok(new { state = 201, msg = "能力点复制成功,复制能力点的文件失败," });
+                }
 
                 //发送消息实体
                 Notification notification = new Notification
@@ -557,12 +565,12 @@ namespace TEAMModelBI.Controllers.BISchool
                     cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.GlobalSite);
                     tableClient = _azureStorage.GetCloudTableClient(BIConst.GlobalSite);
                     blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.GlobalSite);
-                    //serBusClient = _serviceBus.GetServiceBusClient(BIConst.GlobalSite);    //暂未确定使用默认 
+                    serBusClient = _serviceBus.GetServiceBusClient(BIConst.GlobalSite);    //暂未确定使用默认 
                     //activeTask = _configuration.GetValue<string>("GlobalAzure:ServiceBus:ActiveTask");  //暂未确定使用默认
                 }
                 var table = tableClient.GetTableReference("IESLogin");
                 //保存引用记录
-                await table.SaveOrUpdate<AreaQuoteRecord>(new AreaQuoteRecord() { PartitionKey = "QuoteRecord", RowKey = $"{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}", areaId = $"{_oldId}", quoteId = $"{_newId}", quoteName = $"{newName}", standard = $"{_newStandard}" });
+                //await table.SaveOrUpdate<AreaQuoteRecord>(new AreaQuoteRecord() { PartitionKey = "QuoteRecord", RowKey = $"{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}", areaId = $"{_oldId}", quoteId = $"{_newId}", quoteName = $"{newName}", standard = $"{_newStandard}" });
 
                 List<string> abilityIds = new List<string>();  //册别的ID集合
 
@@ -740,7 +748,15 @@ namespace TEAMModelBI.Controllers.BISchool
                 batchCopyFile.tmdName = $"{_tmdName}";
                 var messageBatchCopyFile = new ServiceBusMessage(batchCopyFile.ToJsonString());
                 messageBatchCopyFile.ApplicationProperties.Add("name", "CopyStandardFile");   //Function暂时还未写
-                await serBusClient.SendMessageAsync(activeTask, messageBatchCopyFile);  //先执行删除操作,在执行复制
+                try
+                {
+                    //await _serviceBus.GetServiceBusClient().SendMessageAsync(activeTask, messageBatchCopyFile);  //先执行删除操作,在执行复制  单一
+                    await serBusClient.SendMessageAsync(activeTask, messageBatchCopyFile);  //先执行删除操作,在执行复制
+                }
+                catch (Exception)
+                {
+                    return Ok(new { state = 201 ,msg = "能力点复制成功,复制能力点的文件失败," });
+                }
 
                 //发送消息实体
                 Notification notification = new Notification

+ 122 - 113
TEAMModelBI/Controllers/BISchool/BatchSchoolController.cs

@@ -43,7 +43,6 @@ namespace TEAMModelBI.Controllers.BISchool
         private readonly IHttpClientFactory _http;
         //读取配置信息
         private readonly IConfiguration _configuration;
-        public readonly string mobel = "学校";
 
         public BatchSchoolController(AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage, IOptionsSnapshot<Option> option, IWebHostEnvironment hostingEnvironment, IConfiguration configuration, IHttpClientFactory http)
         {
@@ -141,12 +140,13 @@ namespace TEAMModelBI.Controllers.BISchool
             try
             {
                 var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
-                List<BISchool> schools = new List<BISchool>();
+                List<BISchool> schools = new List<BISchool>(); 
+                List<BISchool> userScs = new List<BISchool>();
                 StringBuilder stringBuilder = new StringBuilder($"{_tmdName}【{_tmdId}】使用批量创校功能:");
                 var cosmosClient = _azureCosmos.GetCosmosClient();
                 var tableClient = _azureStorage.GetCloudTableClient();
                 var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
-                if (foundSchools.site.Equals(BIConst.GlobalSite))
+                if (BIConst.GlobalSite.Equals($"{foundSchools.site}"))
                 {
                     cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.GlobalSite);
                     tableClient = _azureStorage.GetCloudTableClient(BIConst.GlobalSite);
@@ -180,131 +180,140 @@ namespace TEAMModelBI.Controllers.BISchool
                             }
 
                             string tmdId = !string.IsNullOrEmpty(tempTmdId) ? tempTmdId : bischool.admin;
-
-                            CreateSchoolInfo createSchoolInfo = new CreateSchoolInfo()
-                            {
-                                province = bischool.province,
-                                id = "",
-                                name = bischool.name,
-                                city = bischool.city,
-                                aname = "",
-                                createCount = 0,
-                            };
-
-                            //生成学校ID
-                            bool tempStaus = true;
-                            do
-                            {
-                                createSchoolInfo = await SchoolCode.GenerateSchoolCode(createSchoolInfo, _dingDing, _environment);
-                                var schoolStatu = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync($"{createSchoolInfo.id}", new PartitionKey($"Base"));
-                                if (schoolStatu.Status != 200) tempStaus = false;
-                                else createSchoolInfo.createCount = createSchoolInfo.createCount >= 3 ? createSchoolInfo.createCount = 3 : createSchoolInfo.createCount += 1;
-                            } while (tempStaus);
-
-                            if (createSchoolInfo.id != null)
+                            if (!string.IsNullOrEmpty(tmdId))
                             {
-                                string campusId = Guid.NewGuid().ToString();
-                                School upSchool = new School
+                                CreateSchoolInfo createSchoolInfo = new CreateSchoolInfo()
                                 {
-                                    id = createSchoolInfo.id,
-                                    name = bischool.name,
-                                    size = bischool.size == 0 ? 100 : bischool.size,
-                                    code = "Base",
-                                    campuses = new List<Campus> { new Campus { name = bischool.name, id = campusId } },
-                                    region = bischool.region,
                                     province = bischool.province,
+                                    id = "",
+                                    name = bischool.name,
                                     city = bischool.city,
-                                    dist = bischool.dist,
-                                    address = bischool.address,
-                                    picture = "https://teammodelstorage.blob.core.chinacloudapi.cn/0-public/school/bbf54fb3-3fc8-43ae-a358-107281c174cc.png",
-                                    timeZone = new TEAMModelOS.SDK.Models.TimeZone { label = "(UTC+08:00) 北京,重庆,香港特别行政区,乌鲁木齐", value = "+08:00" },
-                                    type = string.IsNullOrEmpty(bischool.type.ToString()) ? 1 : bischool.type,
-                                    pk = "School",
-                                    ttl = -1,
-                                    areaId = string.IsNullOrEmpty(bischool.areaId) ? "" : bischool.areaId,
-                                    standard = string.IsNullOrEmpty(bischool.standard) ? "" : bischool.standard,
-                                    schoolCode = createSchoolInfo.id,
-                                    period = PresetSchoolPeriod(bischool.period, foundSchools.lang, campusId),
-                                    scale = bischool.size >= 300 ? 500 : 0,
-                                    createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
+                                    aname = "",
+                                    createCount = 0,
                                 };
 
-                                stringBuilder.Append($"创建学校:{upSchool.name}【{upSchool.id}】");
-                                //创建学校
-                                await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync<School>(upSchool, new PartitionKey(upSchool.code));
-                                Teacher teacher = null;
-                                try
+                                //生成学校ID
+                                bool tempStaus = true;
+                                do
                                 {
-                                    //查询该教师是否存在
-                                    teacher = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<Teacher>($"{tmdId}", new PartitionKey("Base"));
-                                }
-                                catch
-                                {
-                                }
-                                if (teacher != null)
-                                {
-                                    //教师存在,在该教师信息中添加要管理的学校信息
-                                    teacher.schools.Add(new Teacher.TeacherSchool { areaId = string.IsNullOrEmpty(bischool.areaId) ? "" : bischool.areaId, schoolId = createSchoolInfo.id, name = bischool.name, status = "join", time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() });
-                                    //await cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>(teacher, tmdId, new PartitionKey("Base"));
-                                    SchoolTeacher schoolTeacher = new SchoolTeacher
-                                    {
-                                        id = tmdId,
-                                        code = $"Teacher-{createSchoolInfo.id}",
-                                        roles = new List<string> { "admin", "teacher" },
-                                        job = "管理员",
-                                        name = teacher.name,
-                                        picture = teacher.picture,
-                                        status = "join",
-                                        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
-                                        pk = "Teacher",
-                                        ttl = -1
-                                    };
-                                    stringBuilder.Append($"教师信息:{schoolTeacher.name}【{schoolTeacher.id}】,教师权限:{string.Join(",", schoolTeacher.roles)}");
-                                    await cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>(teacher, teacher.id, new PartitionKey(teacher.code));
-                                    await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync<SchoolTeacher>(schoolTeacher, new PartitionKey(schoolTeacher.code));
-                                }
-                                else
+                                    createSchoolInfo = await SchoolCode.GenerateSchoolCode(createSchoolInfo, _dingDing, _environment);
+                                    var schoolStatu = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync($"{createSchoolInfo.id}", new PartitionKey($"Base"));
+                                    if (schoolStatu.Status != 200) tempStaus = false;
+                                    else createSchoolInfo.createCount = createSchoolInfo.createCount >= 3 ? createSchoolInfo.createCount = 3 : createSchoolInfo.createCount += 1;
+                                } while (tempStaus);
+
+                                if (createSchoolInfo.id != null)
                                 {
-                                    //不存在 新建教师和新建要管理的学校信息
-                                    Teacher addteacher = new Teacher
+                                    string campusId = Guid.NewGuid().ToString();
+                                    School upSchool = new School
                                     {
-                                        id = tmdId,
-                                        pk = "Base",
+                                        id = createSchoolInfo.id,
+                                        name = bischool.name,
+                                        size = bischool.size == 0 ? 100 : bischool.size,
                                         code = "Base",
-                                        name = $"{bischool.name}-管理员"?.ToString(),
-                                        picture = "",
-                                        //创建账号并第一次登录IES5则默认赠送1G
-                                        size = 1,
-                                        defaultSchool = createSchoolInfo.id,
-                                        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
-                                        schools = new List<Teacher.TeacherSchool>() { new Teacher.TeacherSchool { schoolId = createSchoolInfo.id, name = bischool.name, status = "join", time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() } }
+                                        campuses = new List<Campus> { new Campus { name = bischool.name, id = campusId } },
+                                        region = bischool.region,
+                                        province = bischool.province,
+                                        city = bischool.city,
+                                        dist = bischool.dist,
+                                        address = bischool.address,
+                                        picture = "https://teammodelstorage.blob.core.chinacloudapi.cn/0-public/school/bbf54fb3-3fc8-43ae-a358-107281c174cc.png",
+                                        timeZone = new TEAMModelOS.SDK.Models.TimeZone { label = "(UTC+08:00) 北京,重庆,香港特别行政区,乌鲁木齐", value = "+08:00" },
+                                        type = string.IsNullOrEmpty(bischool.type.ToString()) ? 1 : bischool.type,
+                                        pk = "School",
+                                        ttl = -1,
+                                        areaId = string.IsNullOrEmpty(bischool.areaId) ? "" : bischool.areaId,
+                                        standard = string.IsNullOrEmpty(bischool.standard) ? "" : bischool.standard,
+                                        schoolCode = createSchoolInfo.id,
+                                        period = PresetSchoolPeriod(bischool.period, foundSchools.lang, campusId),
+                                        scale = bischool.size >= 300 ? 500 : 0,
+                                        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
                                     };
 
-                                    stringBuilder.Append($"没有该教师信息创建的教师信息:{addteacher.name}【{addteacher.id}】");
-                                    await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").CreateItemAsync<Teacher>(addteacher, new PartitionKey("Base"));
-                                    SchoolTeacher schoolTeacher = new SchoolTeacher
+                                    stringBuilder.Append($"创建学校:{upSchool.name}【{upSchool.id}】");
+                                    //创建学校
+                                    await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync<School>(upSchool, new PartitionKey(upSchool.code));
+                                    Teacher teacher = null;
+                                    try
                                     {
-                                        id = tmdId,
-                                        code = $"Teacher-{createSchoolInfo.id}",
-                                        roles = new List<string> { "admin", "teacher" },
-                                        job = "管理员",
-                                        name = $"{tmdId}-管理员",
-                                        picture = "",
-                                        status = "join",
-                                        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
-                                        pk = "Teacher",
-                                        ttl = -1
-                                    };
+                                        //查询该教师是否存在
+                                        teacher = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<Teacher>($"{tmdId}", new PartitionKey("Base"));
+                                    }
+                                    catch
+                                    {
+                                    }
+                                    if (teacher != null)
+                                    {
+                                        //教师存在,在该教师信息中添加要管理的学校信息
+                                        teacher.schools.Add(new Teacher.TeacherSchool { areaId = string.IsNullOrEmpty(bischool.areaId) ? "" : bischool.areaId, schoolId = createSchoolInfo.id, name = bischool.name, status = "join", time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() });
+                                        //await cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>(teacher, tmdId, new PartitionKey("Base"));
+                                        SchoolTeacher schoolTeacher = new SchoolTeacher
+                                        {
+                                            id = tmdId,
+                                            code = $"Teacher-{createSchoolInfo.id}",
+                                            roles = new List<string> { "admin", "teacher" },
+                                            job = "管理员",
+                                            name = teacher.name,
+                                            picture = teacher.picture,
+                                            status = "join",
+                                            createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                                            pk = "Teacher",
+                                            ttl = -1
+                                        };
+                                        stringBuilder.Append($"教师信息:{schoolTeacher.name}【{schoolTeacher.id}】,教师权限:{string.Join(",", schoolTeacher.roles)}");
+                                        await cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>(teacher, teacher.id, new PartitionKey(teacher.code));
+                                        await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync<SchoolTeacher>(schoolTeacher, new PartitionKey(schoolTeacher.code));
+                                    }
+                                    else
+                                    {
+                                        //不存在 新建教师和新建要管理的学校信息
+                                        Teacher addteacher = new Teacher
+                                        {
+                                            id = tmdId,
+                                            pk = "Base",
+                                            code = "Base",
+                                            name = $"{bischool.name}-管理员"?.ToString(),
+                                            picture = "",
+                                            //创建账号并第一次登录IES5则默认赠送1G
+                                            size = 1,
+                                            defaultSchool = createSchoolInfo.id,
+                                            createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                                            schools = new List<Teacher.TeacherSchool>() { new Teacher.TeacherSchool { schoolId = createSchoolInfo.id, name = bischool.name, status = "join", time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() } }
+                                        };
+
+                                        stringBuilder.Append($"没有该教师信息创建的教师信息:{addteacher.name}【{addteacher.id}】");
+                                        try
+                                        {
+                                            await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").CreateItemAsync<Teacher>(addteacher, new PartitionKey("Base"));
+                                        }
+                                        catch { }
+
+                                        SchoolTeacher schoolTeacher = new SchoolTeacher
+                                        {
+                                            id = tmdId,
+                                            code = $"Teacher-{createSchoolInfo.id}",
+                                            roles = new List<string> { "admin", "teacher" },
+                                            job = "管理员",
+                                            name = $"{tmdId}-管理员",
+                                            picture = "",
+                                            status = "join",
+                                            createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                                            pk = "Teacher",
+                                            ttl = -1
+                                        };
 
-                                    stringBuilder.Append($"教师权限:{string.Join(",", schoolTeacher.roles)}");
-                                    await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync<SchoolTeacher>(schoolTeacher, new PartitionKey(schoolTeacher.code));
+                                        stringBuilder.Append($"教师权限:{string.Join(",", schoolTeacher.roles)}");
+                                        try
+                                        {
+                                            await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync<SchoolTeacher>(schoolTeacher, new PartitionKey(schoolTeacher.code));
+                                        }
+                                        catch { }
+                                    }
                                 }
                             }
+                            else userScs.Add(bischool);
                         }
-                        else 
-                        {
-                            schools.Add(bischool);
-                        }
+                        else schools.Add(bischool);
                     }
                 }
                 else return Ok(new { state = 1, message = "创校信息为空" });
@@ -312,8 +321,8 @@ namespace TEAMModelBI.Controllers.BISchool
                 //保存操作记录
                 //await _azureStorage.SaveBILog("school-batchAdd", stringBuilder?.ToString(), _dingDing, httpContext: HttpContext);
                 await BIAzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "school-batchAdd", stringBuilder?.ToString(), _dingDing, httpContext: HttpContext);
-                if (schools.Count > 0)
-                    return Ok(new { state = 201, message = "已有部分学校批量创建成功;学校已经重复!请检查学校信息!", schools });
+                if (schools.Count > 0 || userScs.Count > 0)
+                    return Ok(new { state = 201, message = "已有部分学校批量创建成功;学校已经重复/或者学校信息有误!请检查学校信息!", schools, userScs });
                 else
                     return Ok(new { state = 200, message = "批量创校已全部完成" });
             }

+ 3 - 0
TEAMModelBI/Startup.cs

@@ -92,6 +92,9 @@ namespace TEAMModelBI
             List<(string name, string connectionString)> storageConnects = new();
             storageConnects.Add(("Default", Configuration.GetValue<string>("Azure:Storage:ConnectionString")));      //大路站ClientString
             storageConnects.Add(("Global", Configuration.GetValue<string>("GlobalAzure:Storage:ConnectionString"))); //国际站ClientString
+
+            storageConnects.Add(("LogChina", Configuration.GetValue<string>("Azure:logStorage:ConnectionString"))); //防火墙日志 大陆站ClientString
+            storageConnects.Add(("LogGlobal", Configuration.GetValue<string>("GlobalAzure:logStorage:ConnectionString"))); //防火墙日志  国际站ClientString
             services.AddBIAzureStorage(storageConnects);
 
             //cosmosDB注入

+ 10 - 1
TEAMModelBI/Tool/Context/BIConst.cs

@@ -3,8 +3,17 @@
     public class BIConst
     {
         /// <summary>
-        /// 国际站点
+        /// 通用数据库国际站点连接字串名称
         /// </summary>
         public static readonly string GlobalSite = "Global";
+
+        /// <summary>
+        /// 中国站防火墙日志连接字串名称
+        /// </summary>
+        public static readonly string LogChinaSite = "LogChina";
+        /// <summary>
+        /// 国际站防火墙日志连接字串名称
+        /// </summary>
+        public static readonly string LogGlobalSite = "LogGlobal";
     }
 }

+ 6 - 1
TEAMModelBI/appsettings.Development.json

@@ -24,6 +24,8 @@
     "Storage": {
       "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodeltest;AccountKey=O2W2vadCqexDxWO+px+QK7y1sHwsYj8f/WwKLdOdG5RwHgW/Dupz9dDUb4c1gi6ojzQaRpFUeAAmOu4N9E+37A==;EndpointSuffix=core.chinacloudapi.cn"
     },
+    "logStorage": { 
+      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodellog;AccountKey=lxVDrgs+6rKtmASL3k1WrarrEd5Rk42wS1Mu5+sqQlPya1JLSlFDtnZUvMPeHHe7zlESfn/1NY7CZdGviy2UCw==;BlobEndpoint=https://teammodellog.blob.core.chinacloudapi.cn/;QueueEndpoint=https://teammodellog.queue.core.chinacloudapi.cn/;TableEndpoint=https://teammodellog.table.core.chinacloudapi.cn/;FileEndpoint=https://teammodellog.file.core.chinacloudapi.cn/;" },
     "Cosmos": {
       "ConnectionString": "AccountEndpoint=https://cdhabookdep-free.documents.azure.cn:443/;AccountKey=JTUVk92Gjsx17L0xqxn0X4wX2thDPMKiw4daeTyV1HzPb6JmBeHdtFY1MF1jdctW1ofgzqkDMFOtcqS46by31A==;"
     },
@@ -47,9 +49,12 @@
     "Storage": {
       "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelstorage;AccountKey=Yq7D4dE6cFuer2d2UZIccTA/i0c3sJ/6ITc8tNOyW+K5f+/lWw9GCos3Mxhj47PyWQgDL8YbVD63B9XcGtrMxQ==;EndpointSuffix=core.chinacloudapi.cn" // 之前未删除连接字符
     },
+    "logStorage": {
+      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodellog;AccountKey=lxVDrgs+6rKtmASL3k1WrarrEd5Rk42wS1Mu5+sqQlPya1JLSlFDtnZUvMPeHHe7zlESfn/1NY7CZdGviy2UCw==;BlobEndpoint=https://teammodellog.blob.core.chinacloudapi.cn/;QueueEndpoint=https://teammodellog.queue.core.chinacloudapi.cn/;TableEndpoint=https://teammodellog.table.core.chinacloudapi.cn/;FileEndpoint=https://teammodellog.file.core.chinacloudapi.cn/;"
+    },
     "Cosmos": {
       //"ConnectionString": "AccountEndpoint=https://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==", //本地
-      "ConnectionString": "AccountEndpoint=https://cdhabookdep-free.documents.azure.cn:443/;AccountKey=JTUVk92Gjsx17L0xqxn0X4wX2thDPMKiw4daeTyV1HzPb6JmBeHdtFY1MF1jdctW1ofgzqkDMFOtcqS46by31A==;"  //测试站
+      "ConnectionString": "AccountEndpoint=https://cdhabookdep-free.documents.azure.cn:443/;AccountKey=JTUVk92Gjsx17L0xqxn0X4wX2thDPMKiw4daeTyV1HzPb6JmBeHdtFY1MF1jdctW1ofgzqkDMFOtcqS46by31A==;" //测试站
     },
     "Redis": {
       "ConnectionString": "52.130.252.100:6379,password=habook,ssl=false,abortConnect=False,writeBuffer=10240"

+ 6 - 0
TEAMModelBI/appsettings.json

@@ -32,6 +32,9 @@
       "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodeltest;AccountKey=O2W2vadCqexDxWO+px+QK7y1sHwsYj8f/WwKLdOdG5RwHgW/Dupz9dDUb4c1gi6ojzQaRpFUeAAmOu4N9E+37A==;EndpointSuffix=core.chinacloudapi.cn"
       //"ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelos;AccountKey=Dl04mfZ9hE9cdPVO1UtqTUQYN/kz/dD/p1nGvSq4tUu/4WhiKcNRVdY9tbe8620nPXo/RaXxs+1F9sVrWRo0bg==;EndpointSuffix=core.chinacloudapi.cn"
     },
+    "logStorage": {
+      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodellog;AccountKey=lxVDrgs+6rKtmASL3k1WrarrEd5Rk42wS1Mu5+sqQlPya1JLSlFDtnZUvMPeHHe7zlESfn/1NY7CZdGviy2UCw==;BlobEndpoint=https://teammodellog.blob.core.chinacloudapi.cn/;QueueEndpoint=https://teammodellog.queue.core.chinacloudapi.cn/;TableEndpoint=https://teammodellog.table.core.chinacloudapi.cn/;FileEndpoint=https://teammodellog.file.core.chinacloudapi.cn/;"
+    },
     "Cosmos": {
       "ConnectionString": "AccountEndpoint=https://cdhabookdep-free.documents.azure.cn:443/;AccountKey=JTUVk92Gjsx17L0xqxn0X4wX2thDPMKiw4daeTyV1HzPb6JmBeHdtFY1MF1jdctW1ofgzqkDMFOtcqS46by31A==;"
       //"ConnectionString": "AccountEndpoint=https://teammodelos.documents.azure.cn:443/;AccountKey=clF73GwPECfP1lKZTCvs8gLMMyCZig1HODFbhDUsarsAURO7TcOjVz6ZFfPqr1HzYrfjCXpMuVD5TlEG5bFGGg==;"
@@ -53,6 +56,9 @@
     "Storage": {
       "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelstorage;AccountKey=Yq7D4dE6cFuer2d2UZIccTA/i0c3sJ/6ITc8tNOyW+K5f+/lWw9GCos3Mxhj47PyWQgDL8YbVD63B9XcGtrMxQ==;EndpointSuffix=core.chinacloudapi.cn" // 之前未删除连接字符
     },
+    "logStorage": {
+      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodellog;AccountKey=lxVDrgs+6rKtmASL3k1WrarrEd5Rk42wS1Mu5+sqQlPya1JLSlFDtnZUvMPeHHe7zlESfn/1NY7CZdGviy2UCw==;BlobEndpoint=https://teammodellog.blob.core.chinacloudapi.cn/;QueueEndpoint=https://teammodellog.queue.core.chinacloudapi.cn/;TableEndpoint=https://teammodellog.table.core.chinacloudapi.cn/;FileEndpoint=https://teammodellog.file.core.chinacloudapi.cn/;"
+    },
     "Cosmos": {
       //"ConnectionString": "AccountEndpoint=https://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==", //本地
       "ConnectionString": "AccountEndpoint=https://cdhabookdep-free.documents.azure.cn:443/;AccountKey=JTUVk92Gjsx17L0xqxn0X4wX2thDPMKiw4daeTyV1HzPb6JmBeHdtFY1MF1jdctW1ofgzqkDMFOtcqS46by31A==;" //测试站

+ 8 - 5
TEAMModelOS.FunctionV4/HttpTrigger/IESHttpTrigger.cs

@@ -464,15 +464,18 @@ namespace TEAMModelOS.FunctionV4.HttpTrigger
                         }
                         await table.SaveOrUpdateAll(DayLoginSchools);//保存学校当月在线数据
                     }
-                    string tbScHourSql = "";
-                    string tbScDaySql = "";
-                    try {
 
                     string tbScHourSql = $"PartitionKey eq 'HourLogin-{school}' and RowKey le '{delTbHour}'";
-                    await table.DeleteStringWhere<HourLogin>(tbScHourSql); //删除学校168小时前的数据
+                    List<HourLogin> scHourLog = await table.QueryWhereString<HourLogin>(tbScHourSql);
+                    if (scHourLog.Count > 0)
+                        //await table.DeleteStringWhere<HourLogin>(tbScHourSql); //删除学校168小时前的数据
+                        await table.DeleteAll(scHourLog);
 
                     string tbScDaySql = $"PartitionKey eq 'DayLogin-{school}' and RowKey le '{delTbDay}'";
-                    await table.DeleteStringWhere<DayLogin>(tbScDaySql); //删除学校180天前的数据
+                    List<DayLogin> scDayLog = await table.QueryWhereString<DayLogin>(tbScDaySql);
+                    if (scDayLog.Count > 0)
+                        await table.DeleteAll(scDayLog);
+                        //await table.DeleteStringWhere<DayLogin>(tbScDaySql); //删除学校180天前的数据
                 }
 
                 await response.WriteAsJsonAsync(new { data = json });

BIN
TEAMModelOS.FunctionV4/libwkhtmltox.dll


+ 12 - 5
TEAMModelOS.SDK/Models/Cosmos/Common/StudentScoreRecord.cs

@@ -14,14 +14,16 @@ namespace TEAMModelOS.SDK.Models.Cosmos.Common
         // id  雪花id
         //code  LessonStudentRecord[-学校编码],  LessonStudentRecord
         //其他基础信息
-        public StudentScoreRecord() {
+        public StudentScoreRecord()
+        {
             pk = "StudentScoreRecord";
         }
         public string stuid { get; set; }
         public string tmdid { get; set; }
+        public string userType { get; set; }
         public string school { get; set; }
         public int year { get; set; }
-        
+
         public List<StudentLessonRecord> lessonRecords { get; set; } = new List<StudentLessonRecord>();
         //单独记录 组计分,个人积分,互动分,
         public double gscore { get; set; } //组计分
@@ -30,12 +32,13 @@ namespace TEAMModelOS.SDK.Models.Cosmos.Common
     }
 
 
-    public class StudentLessonRecord {
+    public class StudentLessonRecord
+    {
         /// <summary>
         ///必填 教师醍摩豆id
         /// </summary>
         public string tmdid { get; set; }
-       // public string tmdname { get; set; }
+        // public string tmdname { get; set; }
         /// <summary>
         ///必填 课堂名称
         /// </summary>
@@ -69,10 +72,14 @@ namespace TEAMModelOS.SDK.Models.Cosmos.Common
         public double pscore { get; set; }  //个人计分
         public double tscore { get; set; } //互动计分
         /// <summary>
+        /// 课例时间
+        /// </summary>
+        public long time { get; set; }
+        /// <summary>
         /// 名单信息
         /// </summary>
         //public List<string> groupIds { get; set; } = new List<string>();
     }
-   
+
 
 }

+ 49 - 30
TEAMModelOS.SDK/Models/Service/LessonService.cs

@@ -17,11 +17,12 @@ namespace TEAMModelOS.SDK.Models.Service
 {
     public class LessonService
     {
-        public static async void DoLessonStudentRecord(DingDing _dingding , SnowflakeId snowflakeId, LessonRecord lessonRecord, string scope, CosmosClient client, string school, string tmdid,
+        public static async void DoLessonStudentRecord(DingDing _dingding, SnowflakeId snowflakeId, LessonRecord lessonRecord, string scope, CosmosClient client, string school, string tmdid,
             Teacher teacher, NotificationService _notificationService, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, IConfiguration _configuration, LessonBase lessonBase)
         {
 
-            try {
+            try
+            {
                 int year = DateTimeOffset.UtcNow.Year;
                 var clientSummaryList = lessonBase.report.clientSummaryList.Where(x => x.groupTaskCompleteCount != 0 || x.groupScore != 0 || x.score != 0 || x.tnteractScore != 0 || x.taskCompleteCount != 0);
                 IEnumerable<LessonStudent> students = new List<LessonStudent>();
@@ -59,12 +60,13 @@ namespace TEAMModelOS.SDK.Models.Service
                 }
                 List<Task<ItemResponse<StudentScoreRecord>>> records = new List<Task<ItemResponse<StudentScoreRecord>>>();
                 stuids.ToList().ForEach(x => {
-                    var record = lessonStudentRecords.Find(l => l.id.Equals(x.id) && l.code.Equals($"StudentScoreRecord") && l.school.Equals(x.school) );
+                    var record = lessonStudentRecords.Find(l => l.id.Equals(x.id) && l.code.Equals($"StudentScoreRecord") && l.school.Equals(x.school));
                     ClientSummaryList clientSummaryList = lessonBase.report.clientSummaryList.Find(c => c.seatID == x.seatID);
                     if (record != null)
                     {
                         if (clientSummaryList != null)
                         {
+                            //排查重复课例的数据。》》》》》》》》》》》》》》》》》》》》》
                             record.lessonRecords.Add(
                                  new StudentLessonRecord
                                  {
@@ -78,15 +80,17 @@ namespace TEAMModelOS.SDK.Models.Service
                                      courseId = lessonRecord.courseId,
                                      periodId = lessonRecord.periodId,
                                      subjectId = lessonRecord.subjectId,
+                                     time = lessonRecord.startTime
                                  }
                              );
                         }
                     }
                     else
                     {
-
+                        //排查重复课例的数据。》》》》》》》》》》》》》》》》》》》》》
                         record = new StudentScoreRecord
                         {
+                            userType = Constant.ScopeStudent,
                             id = $"{snowflakeId.NextId()}",
                             year = year,
                             stuid = x.id,
@@ -110,6 +114,10 @@ namespace TEAMModelOS.SDK.Models.Service
                         };
 
                     }
+                    record.userType = Constant.ScopeStudent;
+                    record.gscore = record.lessonRecords.Select(x => x.gscore).Sum();
+                    record.pscore = record.lessonRecords.Select(x => x.pscore).Sum();
+                    record.tscore = record.lessonRecords.Select(x => x.tscore).Sum();
                     records.Add(client.GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(record, partitionKey: new PartitionKey(record.code)));
                 });
                 tmdids.ToList().ForEach(x => {
@@ -118,7 +126,7 @@ namespace TEAMModelOS.SDK.Models.Service
                     if (record != null)
                     {
                         if (clientSummaryList != null)
-                        {
+                        {  //排查重复课例的数据。》》》》》》》》》》》》》》》》》》》》》
                             record.lessonRecords.Add(
                             new StudentLessonRecord
                             {
@@ -136,18 +144,20 @@ namespace TEAMModelOS.SDK.Models.Service
                         }
                     }
                     else
-                    {
+                    {  //排查重复课例的数据。》》》》》》》》》》》》》》》》》》》》》
                         record = new StudentScoreRecord
                         {
+                            userType = Constant.ScopeTmdUser,
                             id = $"{snowflakeId.NextId()}",
                             code = $"StudentScoreRecord",
                             pk = "StudentScoreRecord",
                             ttl = -1,
                             year = year,
                             tmdid = x.id,
-                            lessonRecords = new List<StudentLessonRecord> {
-                            new StudentLessonRecord
-                             {
+                            lessonRecords = new List<StudentLessonRecord> 
+                            {
+                                new StudentLessonRecord
+                                {
                                  gscore = clientSummaryList.groupScore,
                                  pscore = clientSummaryList.score,
                                  tscore = clientSummaryList.tnteractScore,
@@ -158,10 +168,11 @@ namespace TEAMModelOS.SDK.Models.Service
                                  courseId = lessonRecord.courseId,
                                  periodId = lessonRecord.periodId,
                                  subjectId = lessonRecord.subjectId,
+                                }
                             }
-                        }
                         };
                     }
+                    record.userType = Constant.ScopeStudent;
                     record.gscore = record.lessonRecords.Select(x => x.gscore).Sum();
                     record.pscore = record.lessonRecords.Select(x => x.pscore).Sum();
                     record.tscore = record.lessonRecords.Select(x => x.tscore).Sum();
@@ -171,13 +182,16 @@ namespace TEAMModelOS.SDK.Models.Service
                 {
                     await Task.WhenAll(records);
                 }
-            } catch (Exception ex ) {
-                await  _dingding.SendBotMsg($"学生个人课例统计信息异常,{ex.Message}\n{ex.StackTrace}",GroupNames.醍摩豆服務運維群組);
+            }
+            catch (Exception ex)
+            {
+                await _dingding.SendBotMsg($"学生个人课例统计信息异常,{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
             }
         }
 
-        public static async void DoAutoDeleteSchoolLessonRecord(LessonRecord lessonRecord,string  scope ,CosmosClient client,string school,string tmdid,
-            Teacher teacher, NotificationService _notificationService, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, IConfiguration _configuration) {
+        public static async void DoAutoDeleteSchoolLessonRecord(LessonRecord lessonRecord, string scope, CosmosClient client, string school, string tmdid,
+            Teacher teacher, NotificationService _notificationService, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, IConfiguration _configuration)
+        {
             if (lessonRecord.scope.Equals("school"))
             {
                 SchoolSetting setting = null;
@@ -203,7 +217,7 @@ namespace TEAMModelOS.SDK.Models.Service
                 {
                     setting = new SchoolSetting() { lessonSetting = new LessonSetting { openAutoClean = 0, expireDays = Constant.school_lesson_expire } };
                 }
-                int school_lesson_expire =0;
+                int school_lesson_expire = 0;
                 bool save = true;
                 List<string> msg = new List<string>();
                 if (setting.lessonSetting.openAutoClean == 1)
@@ -212,7 +226,8 @@ namespace TEAMModelOS.SDK.Models.Service
                     {
                         save = false;
                     }
-                    else {
+                    else
+                    {
                         school_lesson_expire = setting.lessonSetting.expireDays;
                         foreach (var item in setting.lessonSetting.conds)
                         {
@@ -386,7 +401,8 @@ namespace TEAMModelOS.SDK.Models.Service
                         }
                     }
                 }
-                else {
+                else
+                {
                     save = false;
                     school_lesson_expire = Constant.school_lesson_expire;
                 }
@@ -401,14 +417,14 @@ namespace TEAMModelOS.SDK.Models.Service
                     //result.Add(3, day3);
                     //剩余1天的通知
                     var day1 = now.AddDays(school_lesson_expire - (school_lesson_expire - 1)).ToUnixTimeMilliseconds();
-                    result.Add(1, new ExpireTag { expire= day1 ,tag= "notification" });
+                    result.Add(1, new ExpireTag { expire = day1, tag = "notification" });
                     //到期通知
                     //不到五点上传的课例,七天之后直接删除。
                     int addSecond = 0;
                     if (now.Hour > 5)
                     {
                         // 到凌晨00点还差 (24 - now.Hour) *60 * 60 分钟,再加天数;
-                        addSecond = school_lesson_expire * 86400 + (24 - now.Hour) * 3600-(now.Hour* 3600);
+                        addSecond = school_lesson_expire * 86400 + (24 - now.Hour) * 3600 - (now.Hour * 3600);
                         //再加 00到05小时内的 随机秒数
                         Random rand = new Random();
                         int randInt = rand.Next(0, 18000);
@@ -420,13 +436,13 @@ namespace TEAMModelOS.SDK.Models.Service
                     }
                     lessonRecord.expire = now.AddSeconds(addSecond).ToUnixTimeMilliseconds();
                     result.Add(school_lesson_expire, new ExpireTag { expire = lessonRecord.expire, tag = "delete" });
-                   // result.Add(school_lesson_expire, lessonRecord.expire);
+                    // result.Add(school_lesson_expire, lessonRecord.expire);
                     string biz = "expire";
                     Notification notification = new Notification
                     {
                         hubName = "hita",
                         type = "msg",
-                        from = $"ies5:{ Environment.GetEnvironmentVariable("Option:Location")}:private",
+                        from = $"ies5:{Environment.GetEnvironmentVariable("Option:Location")}:private",
                         to = new List<string> { tmdid },
                         label = $"{biz}_lessonRecord",
                         body = new
@@ -491,7 +507,8 @@ namespace TEAMModelOS.SDK.Models.Service
                         }
                     }
                 }
-                else {
+                else
+                {
 
                     if (lessonRecord.expire > 0)
                     {
@@ -517,7 +534,8 @@ namespace TEAMModelOS.SDK.Models.Service
         }
 
 
-        public record ExpireTag {
+        public record ExpireTag
+        {
             public long expire { get; set; }
             public string tag { get; set; }
         }
@@ -536,7 +554,7 @@ namespace TEAMModelOS.SDK.Models.Service
                 lessonDis.record = 1;
             }
             //删除数据的情况
-           //不再对LessonCount进行减
+            //不再对LessonCount进行减
             else if (oldRecord != null && newRecord == null)
             {
                 /*lessonDis.record = -1;
@@ -679,11 +697,12 @@ namespace TEAMModelOS.SDK.Models.Service
                         code = $"LessonCount-{data.school}-{year}";
                         tbname = "School";
                     }
-                    else {
+                    else
+                    {
                         code = $"LessonCount-{data.school}-{year}-{data.periodId}";
                         tbname = "School";
                     }
-                    
+
                 }
                 else
                 {
@@ -712,10 +731,10 @@ namespace TEAMModelOS.SDK.Models.Service
                         ttl = -1
                     };
                     double[] da = new double[days];
-                    List<double> list = new (da);
-                    List<double> listT = new (da);
-                    List<double> listP = new (da);
-                    List<double> listPT = new (da);
+                    List<double> list = new(da);
+                    List<double> listT = new(da);
+                    List<double> listP = new(da);
+                    List<double> listPT = new(da);
 
                     list[day - 1] += lessonDis.record;
                     listT[day - 1] += lessonDis.disTCount;

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 138 - 135
TEAMModelOS/ClientApp/public/lang/en-US.js


+ 88 - 85
TEAMModelOS/ClientApp/public/lang/zh-CN.js

@@ -382,66 +382,69 @@ const LANG_ZH_CN = {
         toAuth: '前往授权',
         periodInfo1: '学校学段数量',
         periodInfo2: '学校学院数量',
-        searchSerial: '搜索序列号',
-        noDeviceName: '暂无设备名称',
-        noClassId: '未关联教室',
-        rltClass: '关联教室',
-        unrltClass: '解绑教室',
-        unbdDeviceCont: '确认解绑当前设备吗?',
-        unbdOk: '解绑成功',
-        unbdErr1: '设备ID错误',
-        unbdErr2: '序列号异常',
-        unMatchRoom: '未匹配到教室',
-        deviceName: '设备名称:',
-        bandOk: '绑定成功',
-        bandErr: '绑定失败',
-        unbdRoomCt: '确定解绑当前教室吗?',
-        unbdOk: '解绑成功',
-        unbdErr: '解绑失败',
-        pdName1: '学情分析模组',
-        pdName2: '智慧学校管理服务',
-        pdName3: '卷卡合一阅卷系统',
-        pdName4: 'AClass ONE智慧学伴',
-        pdName5: '数据储存服务空间',
-        pdName6: 'Haboard醍摩豆智慧大屏',
-        authDate: '有效期:',
-        fuAuth: '功能权限:',
-        IRSnumber: 'IRS链接数:',
-        bandDeviceNO: '可绑定硬件数:',
-        svcName: '服务名称:',
-        authType: '授权方式:',
-        authType1: '新约',
-        authType2: '续约',
-        authNumber: '购买数量:',
-        text1: '设备名称:',
-        text2: '硬件:',
-        text3: '服务类型:',
-        text4: '智慧教室:',
-        contactUs: '联系我们',
-        learnMore: '了解更多',
-        ctFrom: '联系表单',
-        ctFmText1: '您好,欢迎留下联络事项,我们将尽快与您联系。',
-        ctFmText2: '姓名',
-        ctFmText3: '请输入姓名',
-        ctFmText4: '性别',
-        ctFmText5: '先生',
-        ctFmText6: '女士',
-        ctFmText7: '联系电话',
-        ctFmText8: '请输入联系电话',
-        ctFmText9: '请选择性别',
-        ctFmText10: '请输入联系电话',
-        ctFmText11: '请完善表单信息',
-        ctFmText12: '所在地区',
-        ctFmText13: '咨询内容',
-        ctFmText14: '服务存储空间',
-        ctFmText15: '其他',
-        ctFmText16: '请选择所在地区',
-        ctFmText17: '请选择咨询内容',
-        ctFmText18: '保存成功,稍后我们将与您联系',
-        ctFmText19: '保存失败',
-        ctFmText20: '智慧教室',
-        ctFmText21: '研修中心',
-        ctFmText22: '顾问服务',
+        searchSerial:'搜索序列号',
+        noDeviceName:'暂无设备名称',
+        noClassId:'未关联教室',
+        rltClass:'关联教室',
+        unrltClass:'解绑教室',
+        unbdDeviceCont:'确认解绑当前设备吗?',
+        unbdOk:'解绑成功',
+        unbdErr1:'设备ID错误',
+        unbdErr2:'序列号异常',
+        unMatchRoom:'未匹配到教室',
+        deviceName:'设备名称:',  
+        bandOk:'绑定成功',
+        bandErr:'绑定失败',
+        unbdRoomCt:'确定解绑当前教室吗?',
+        unbdOk:'解绑成功',
+        unbdErr:'解绑失败',
+        pdName1:'学情分析模组',
+        pdName2:'智慧学校管理服务',
+        pdName3:'卷卡合一阅卷系统',
+        pdName4:'AClass ONE智慧学伴',
+        pdName5:'数据储存服务空间',
+        pdName6:'Haboard醍摩豆智慧大屏',
+        authDate:'有效期:',
+        fuAuth:'功能权限:',
+        IRSnumber:'IRS链接数:',
+        bandDeviceNO:'可绑定硬件数:',
+        svcName:'服务名称:',
+        authType:'授权方式:',
+        authType1:'新约',
+        authType2:'续约',
+        authNumber:'购买数量:',
+        text1:'设备名称:',
+        text2:'硬件:',
+        text3:'服务类型:',
+        text4:'智慧教室:',
+        contactUs:'联系我们',
+        learnMore:'了解更多',
+        ctFrom:'联系表单',
+        ctFmText1:'您好,欢迎留下联络事项,我们将尽快与您联系。',
+        ctFmText2:'姓名',
+        ctFmText3:'请输入姓名',
+        ctFmText4:'性别',
+        ctFmText5:'先生',
+        ctFmText6:'女士',
+        ctFmText7:'联系电话',
+        ctFmText8:'请输入联系电话',
+        ctFmText9:'请选择性别',
+        ctFmText10:'请输入联系电话',
+        ctFmText11:'请完善表单信息',
+        ctFmText12:'所在地区',
+        ctFmText13:'咨询内容',
+        ctFmText14:'服务存储空间',
+        ctFmText15:'其他',
+        ctFmText16:'请选择所在地区',
+        ctFmText17:'请选择咨询内容',
+        ctFmText18:'保存成功,稍后我们将与您联系',
+        ctFmText19:'保存失败',
+        ctFmText20:'智慧教室',
+        ctFmText21:'研修中心',
+        ctFmText22:'顾问服务',
+        ctFmText23:'电子邮箱',
+        ctFmText24:'请输入邮箱',
+        ctFmText25:'邮箱格式不正确',
     },
     // 班级管理
     classMgmt: {
@@ -849,21 +852,21 @@ const LANG_ZH_CN = {
         nicknameTips: '请输入学生昵称',
         evRcd: '历次评测',
         gradeErr: '查询成绩数据失败',
-        rcdExpired: '到期',
-        cusTab1: '评测活动',
-        cusTab2: '作业活动',
-        cusTab3: '投票活动',
-        cusTab4: '问卷活动',
-        cusTab5: '班级公告',
-        cusTab6: '评测列表',
-        cusTab7: '成绩统计',
-        cusTab8: '新建评测',
-        cusTab9: '新建作业',
-        cusTab10: '新建公告',
-        cusTab11: '新建问卷',
-        cusTab12: '新建投票',
-        fullTips1: '学校空间已满,无法创建学校课程评测',
-        fullTips2: '个人空间已满,无法创建个人课程评测',
+        rcdExpired:'到期',
+        cusTab1:'评测活动',
+        cusTab2:'作业活动',
+        cusTab3:'投票活动',
+        cusTab4:'问卷活动',
+        cusTab5:'班级公告',
+        cusTab6:'评测列表',
+        cusTab7:'成绩统计',
+        cusTab8:'新建评测',
+        cusTab9:'新建作业',
+        cusTab10:'新建公告',
+        cusTab11:'新建问卷',
+        cusTab12:'新建投票',
+        fullTips1:'学校空间已满,无法创建学校课程评测',
+        fullTips2:'个人空间已满,无法创建个人课程评测',
 
         //ManageClass.vue
         stuMgt: '学生管理',
@@ -1114,16 +1117,16 @@ const LANG_ZH_CN = {
             optionCount: '选项分布',
             tPushLabel: '推送:',
             noAns: '未答',
-            filter1: '所有',
-            filter2: '推送',
-            filter3: '任务',
-            filter4: '互动',
-            filter5: '测验',
-            evt1: '抢权:',
-            evt2: '课中评测数据',
-            evt3: '挑人:',
-            evt4: '收集:',
-            evt5: '收集的作品',
+            filter1:'所有',
+            filter2:'推送',
+            filter3:'任务',
+            filter4:'互动',
+            filter5:'测验',
+            evt1:'抢权:',
+            evt2:'课中评测数据',
+            evt3:'挑人:',
+            evt4:'收集:',
+            evt5:'收集的作品',
         }
     },
     // ElementUI相关

+ 109 - 106
TEAMModelOS/ClientApp/public/lang/zh-TW.js

@@ -382,66 +382,69 @@ const LANG_ZH_TW = {
         toAuth: '前往授權',
         periodInfo1: '學校學段數量',
         periodInfo2: '學校學院數量',
-        searchSerial: '搜尋序號',
-        noDeviceName: '暫無設備名稱',
-        noClassId: '未關聯教室',
-        rltClass: '關聯教室',
-        unrltClass: '解除關聯教室',
-        unbdDeviceCont: '確認解綁當前序號嗎?',
-        unbdOk: '解綁成功',
-        unbdErr1: '設備ID錯誤',
-        unbdErr2: '序號異常',
-        unMatchRoom: '未匹配到教室',
-        deviceName: '設備名稱:',
-        bandOk: '綁定成功',
-        bandErr: '綁定失敗',
-        unbdRoomCt: '確定解除關聯當前教室嗎?',
-        unbdOk: '解除成功',
-        unbdErr: '解除失敗',
-        pdName1: '學情分析模組',
-        pdName2: '智慧學校管理服務',
-        pdName3: '卷卡合一閱卷系統',
-        pdName4: 'AClass ONE智慧學伴',
-        pdName5: '數據儲存服務空間',
-        pdName6: 'Haboard醍摩豆智慧大屏',
-        authDate: '有效期:',
-        fuAuth: '功能權限:',
-        IRSnumber: 'IRS連線數:',
-        bandDeviceNO: '可綁定設備數:',
-        svcName: '服務名稱:',
-        authType: '授權方式:',
-        authType1: '新約',
-        authType2: '續約',
-        authNumber: '購買數量:',
-        text1: '設備名稱:',
-        text2: '設備:',
-        text3: '服務類型:',
-        text4: '智慧教室:',
-        contactUs: '聯系我們',
-        learnMore: '了解更多',
-        ctFrom: '聯系表單',
-        ctFmText1: '您好,歡迎留下聯絡事項,我們將盡快與您聯系。',
-        ctFmText2: '姓名',
-        ctFmText3: '請輸入姓名',
-        ctFmText4: '性別',
-        ctFmText5: '先生',
-        ctFmText6: '女士',
-        ctFmText7: '聯系電話',
-        ctFmText8: '請輸入聯系電話',
-        ctFmText9: '請選擇性別',
-        ctFmText10: '請輸入聯系電話',
-        ctFmText11: '請完善表單信息',
-        ctFmText12: '所在地區',
-        ctFmText13: '咨詢內容',
-        ctFmText14: '服務存儲空間',
-        ctFmText15: '其他',
-        ctFmText16: '請選擇所在地區',
-        ctFmText17: '請選擇咨詢內容',
-        ctFmText18: '保存成功,稍後我們將與您聯系',
-        ctFmText19: '保存失敗',
-        ctFmText20: '智慧教室',
-        ctFmText21: '研修中心',
-        ctFmText22: '顧問服務',
+        searchSerial:'搜尋序號',
+        noDeviceName:'暫無設備名稱',
+        noClassId:'未關聯教室',
+        rltClass:'關聯教室',
+        unrltClass:'解除關聯教室',
+        unbdDeviceCont:'確認解綁當前序號嗎?',
+        unbdOk:'解綁成功',
+        unbdErr1:'設備ID錯誤',
+        unbdErr2:'序號異常',
+        unMatchRoom:'未匹配到教室',
+        deviceName:'設備名稱:',   
+        bandOk:'綁定成功',
+        bandErr:'綁定失敗',
+        unbdRoomCt:'確定解除關聯當前教室嗎?',
+        unbdOk:'解除成功',
+        unbdErr:'解除失敗',
+        pdName1:'學情分析模組',
+        pdName2:'智慧學校管理服務',
+        pdName3:'卷卡合一閱卷系統',
+        pdName4:'AClass ONE智慧學伴',
+        pdName5:'數據儲存服務空間',
+        pdName6:'Haboard醍摩豆智慧大屏',
+        authDate:'有效期:',
+        fuAuth:'功能權限:',
+        IRSnumber:'IRS連線數:',
+        bandDeviceNO:'可綁定設備數:',
+        svcName:'服務名稱:',
+        authType:'授權方式:',
+        authType1:'新約',
+        authType2:'續約',
+        authNumber:'購買數量:',
+        text1:'設備名稱:',
+        text2:'設備:',
+        text3:'服務類型:',
+        text4:'智慧教室:',
+        contactUs:'聯繫我們',
+        learnMore:'了解更多',
+        ctFrom:'聯繫表單',
+        ctFmText1:'您好,歡迎留下聯絡事項,我們將盡快與您聯繫。',
+        ctFmText2:'姓名',
+        ctFmText3:'請輸入姓名',
+        ctFmText4:'性別',
+        ctFmText5:'先生',
+        ctFmText6:'女士',
+        ctFmText7:'聯繫電話',
+        ctFmText8:'請輸入聯繫電話',
+        ctFmText9:'請選擇性別',
+        ctFmText10:'請輸入聯繫電話',
+        ctFmText11:'請完善表單信息',
+        ctFmText12:'所在地區',
+        ctFmText13:'諮詢內容',
+        ctFmText14:'服務存儲空間',
+        ctFmText15:'其他',
+        ctFmText16:'請選擇所在地區',
+        ctFmText17:'請選擇諮詢內容',
+        ctFmText18:'保存成功,稍後我們將與您聯繫',
+        ctFmText19:'保存失敗',
+        ctFmText20:'智慧教室',
+        ctFmText21:'研修中心',
+        ctFmText22:'顧問服務',
+        ctFmText23:'電子郵箱',
+        ctFmText24:'請輸入郵箱',
+        ctFmText25:'郵箱格式不正確',
     },
     // 班级管理
     classMgmt: {
@@ -571,7 +574,7 @@ const LANG_ZH_TW = {
     },
     // 课堂管理
     courseManage: {
-        addCourse: '新課程',
+        addCourse: '新課程',
         courseList: '課程清單',
         courseList1: '我的課程',
         courseShow: '顯示所有課程',
@@ -651,7 +654,7 @@ const LANG_ZH_TW = {
             studentTableC10: '編制班',
             studentTableC11: '暱稱',
             addClassroomProp1: '選擇預設教室',
-            addClassroomProp2: '新個人教室',
+            addClassroomProp2: '新個人教室',
             chooseClassroom: '請選擇系統的教室',
             searchHolder1: '關鍵字搜尋',
             classroomTableC1: '教室編碼',
@@ -849,21 +852,21 @@ const LANG_ZH_TW = {
         nicknameTips: '請輸入學生暱稱',
         evRcd: '歷次評量',
         gradeErr: '查詢成績數據失敗',
-        rcdExpired: '到期',
-        cusTab1: '評測活動',
-        cusTab2: '作業活動',
-        cusTab3: '投票活動',
-        cusTab4: '問卷活動',
-        cusTab5: '班級公告',
-        cusTab6: '評測列表',
-        cusTab7: '成績統計',
-        cusTab8: '新建評測',
-        cusTab9: '新建作業',
-        cusTab10: '新建公告',
-        cusTab11: '新建問卷',
-        cusTab12: '新建投票',
-        fullTips1: '學校空間已滿,無法創建學校課程評測',
-        fullTips2: '個人空間已滿,無法創建個人課程評測',
+        rcdExpired:'到期',
+        cusTab1:'評測活動',
+        cusTab2:'作業活動',
+        cusTab3:'投票活動',
+        cusTab4:'問卷活動',
+        cusTab5:'班級公告',
+        cusTab6:'評測列表',
+        cusTab7:'成績統計',
+        cusTab8:'新建評測',
+        cusTab9:'新建作業',
+        cusTab10:'新建公告',
+        cusTab11:'新建問卷',
+        cusTab12:'新建投票',
+        fullTips1:'學校空間已滿,無法創建學校課程評測',
+        fullTips2:'個人空間已滿,無法創建個人課程評測',
 
         //ManageClass.vue
         stuMgt: '學生管理',
@@ -931,7 +934,7 @@ const LANG_ZH_TW = {
         saveLabel: '儲存變更',
         addStuList: '新增名單',
         addListType: '方式',
-        addListType1: '新名單',
+        addListType1: '新名單',
         addListType2: '選擇已有名單',
         listLabel: '名單',
         removeList: '移除名單',
@@ -950,7 +953,7 @@ const LANG_ZH_TW = {
         listType2: '選課班',
         confirmAdd: '確認新增',
         cancelAdd: '取消新增',
-        createList: '新選課班',
+        createList: '新選課班',
         name: '名稱:',
         nameHolder: '請輸入名單名稱…',
         nameRepeat: '選課班名稱重複',
@@ -1114,16 +1117,16 @@ const LANG_ZH_TW = {
             optionCount: '選項分佈',
             tPushLabel: '推送:',
             noAns: '未答',
-            filter1: '所有',
-            filter2: '推送',
-            filter3: '任務',
-            filter4: '互動',
-            filter5: '測驗',
-            evt1: '搶權:',
-            evt2: '課中評量數據',
-            evt3: '挑人:',
-            evt4: '收集:',
-            evt5: '收集的作品',
+            filter1:'所有',
+            filter2:'推送',
+            filter3:'任務',
+            filter4:'互動',
+            filter5:'測驗',
+            evt1:'搶權:',
+            evt2:'課中評量數據',
+            evt3:'挑人:',
+            evt4:'收集:',
+            evt5:'收集的作品',
         }
     },
     // ElementUI相关
@@ -1210,7 +1213,7 @@ const LANG_ZH_TW = {
         index: {
             item: '試題',
             paper: '試卷',
-            addExercise: '新試題',
+            addExercise: '新試題',
             openAll: '全部展開',
             collapseAll: '全部折疊',
             autoCreate: '智慧組卷',
@@ -1281,8 +1284,8 @@ const LANG_ZH_TW = {
         cancelSuc: '取消成功',
         addSuc: '新增成功',
         newExercise: {
-            newSchoolItem: '新學校題目',
-            newPrivateItem: '新個人題目',
+            newSchoolItem: '新學校題目',
+            newPrivateItem: '新個人題目',
             backToBank: '返回題庫',
             choosePeriod: '選擇學制',
             chooseGrade: '選擇年級',
@@ -2142,7 +2145,7 @@ const LANG_ZH_TW = {
         delete: '刪除',
         moveBlock: '移出知識塊',
         searchBlock: '搜尋知識塊',
-        buildBlock: '新知識塊',
+        buildBlock: '新知識塊',
         pointCount: '知識點數:',
         editBlock: '編輯知識塊',
         addPoint: '新增知識點',
@@ -2194,7 +2197,7 @@ const LANG_ZH_TW = {
             listLabel1: '學校評量',
             listLabel2: '個人評量',
             period: '學制:',
-            create: '新',
+            create: '新',
             delete: '刪除',
             edit: '編輯',
             createTime: '施測時間:',
@@ -2259,8 +2262,8 @@ const LANG_ZH_TW = {
             shareText6: '快速登入醍摩豆雲平臺IES學習主頁,進行線上活動',
             shareText7: '或登入醍摩豆雲平臺IES學習主頁,進行線上活動:',
             shareText8: '掃碼進行線上活動',
-            shareText9: '製評量通知',
-            shareText10: '復製評量鏈接',
+            shareText9: '製評量通知',
+            shareText10: '複製評量網址',
             shareText11: '為了更好的用戶體驗,請在PC端完成線上活動!',
             copy: '複製',
             copyTitle: '複製評量',
@@ -3254,7 +3257,7 @@ const LANG_ZH_TW = {
         periodCountTips: '學段數量根據學校購買進行分配,學校只能進行編輯學段名稱,不能新增和刪除學段。',
         cgCountTips: '學院數量根據學校購買進行分配,學校只能進行編輯學院名稱,不能新增和刪除學院。',
         addSubjectType: '新增方式',
-        addSubjectType1: '新學科',
+        addSubjectType1: '新學科',
         addSubjectType2: '選擇已有學科',
         addSubjectType3: '已有學科',
         addSubjectType4: '請選擇需要新增的學科',
@@ -3397,7 +3400,7 @@ const LANG_ZH_TW = {
         updOk: '修改成功',
         updErr: '修改失敗',
         warmTips: '溫馨提示',
-        mobileTips: '為了您更好的使用體驗,建議使用PC端訪問IES5雲平臺!',
+        mobileTips:'為了您更好的使用體驗,建議使用PC端訪問IES5雲平臺!',
         noStuContent: '學校暫未匯入學生帳號,是否前往學生管理匯入學生帳號?',
         setIrsWarning: '請設定IRS編號',
         setNoWarning: '請設定座號'
@@ -4802,7 +4805,7 @@ const LANG_ZH_TW = {
         chooseTargetTip: '請先選擇分享對象!',
         chooseShareChapterTip: '請先選擇需要分享的章節!',
         chooseChapterTip: '請先選擇需要收藏的章節!',
-        chooseVolumeTip: '請選擇已新增的冊別或者新冊別!',
+        chooseVolumeTip: '請選擇已新增的冊別或者新冊別!',
         playFailTip: '資源暫不支援播放',
         shareSyllabus: '分享個人課綱',
         chooseShareChapter: '選擇分享的章節',
@@ -4813,7 +4816,7 @@ const LANG_ZH_TW = {
         allSave: '整冊收藏',
         chooseSavePos: '選擇收藏位置',
         pos1: '已有冊別',
-        pos2: '新冊別',
+        pos2: '新冊別',
         chooseVolume: '選擇一個冊別',
         newVolume: '輸入新冊別名稱',
         confirmSave: '確認收藏',
@@ -4837,7 +4840,7 @@ const LANG_ZH_TW = {
         search: '搜尋',
         edit: '編輯',
         delete: '刪除',
-        add: '新冊別',
+        add: '新冊別',
         place1: '輸入冊別名稱…',
         isDel: '已失效',
         deleteDelV: '刪除失效冊別',
@@ -4947,7 +4950,7 @@ const LANG_ZH_TW = {
     },
     // 系统相关
     system: {
-        wechatTip: '關注醍摩豆微信公眾號詢',
+        wechatTip: '關注醍摩豆微信公眾號詢',
         wechatTipTw: '透過QR Code加入Line官方客服',
         preview: '預覽',
         title: '醍摩豆雲平臺',
@@ -5118,7 +5121,7 @@ const LANG_ZH_TW = {
         text65: "播放影片",
         text66: "換頁",
     },
-    // 阅卷任务
+    // 閱卷任務
     task: {
         markTask: '閱卷任務',
         markStatus0: '未開始',
@@ -6214,9 +6217,9 @@ const LANG_ZH_TW = {
     },
     // 投票活动
     vote: {
-        copyNotice: '複製活動通知',
-        copyLinkUrl: '複製活動鏈接',
-        fullTip: '資源空間已滿,無法建立新活動!',
+        copyNotice:'複製活動通知',
+        copyLinkUrl:'複製活動鏈接',
+        fullTip:'資源空間已滿,無法建立新活動!',
         secret: '匿名',
         allTeacher: '所有老師',
         noFindVote: '未查詢到當前活動!',

+ 8 - 8
TEAMModelOS/ClientApp/src/utils/editorLangTw.js

@@ -1,9 +1,9 @@
 let editor_tw_config = {
     wangEditor: {
-        重置: '重',
+        重置: '重',
         插入: '插入',
-        默认: '默認',
-        创建: '建',
+        默认: '預設',
+        创建: '建',
         修改: '修改',
         如: '連結URL,如',
         请输入正文: '請輸入正文',
@@ -30,7 +30,7 @@ let editor_tw_config = {
                 表格: '表格',
                 代码: '程式碼',
                 分割线: '分割線',
-                恢复: '復',
+                恢复: '復',
                 撤销: '撤銷',
                 全屏: '全屏',
                 代办事项: '代辦事項',
@@ -69,7 +69,7 @@ let editor_tw_config = {
 					插入公式:'插入公式',
 				},
                 emoticon: {
-                    默认: '默認',
+                    默认: '預設',
                     新浪: '新浪',
                     emoji: 'emoji',
                     手势: '手勢',
@@ -77,14 +77,14 @@ let editor_tw_config = {
                 image: {
                     图片链接: '圖片連結',
                     上传图片: '上傳圖片',
-                    网络图片: '網圖片',
+                    网络图片: '網圖片',
                 },
                 link: {
                     链接: '連結',
                     链接文字: '連結描述',
                     删除链接: '删除連結',
                     查看链接: '查看連結',
-					取消链接: '取消鏈接',
+					取消链接: '取消連結',
                 },
                 video: {
                     插入视频: '插入視頻',
@@ -126,7 +126,7 @@ let editor_tw_config = {
             服务器返回状态: '服務器返回狀態',
             上传图片返回结果错误: '上傳圖片返回結果錯誤',
             请替换为支持的图片类型: '請替換為支持的圖片類型',
-            您插入的网络图片无法识别: '您插入的網圖片無法識別',
+            您插入的网络图片无法识别: '您插入的網圖片無法識別',
             您刚才插入的图片链接未通过编辑器校验: '您剛才插入的圖片連結未通過編輯器校驗',
         },
     }

+ 4 - 4
TEAMModelOS/ClientApp/src/view/ability/Review.vue

@@ -202,7 +202,7 @@ export default {
         if (this.hasModify) {
           this.$Modal.confirm({
             title: '温馨提示',
-              content: '您未确认“提交评审结果”,无法保存修改内容,是否确认离开?',
+            content: '您未确认“提交评审结果”,无法保存修改内容,是否确认离开?',
             onOk: () => {
               this.$emit('goBack', {
                 needRefresh: needFresh
@@ -308,7 +308,7 @@ export default {
       console.log(file)
       console.log(fullFilePath)
       let isImg = ['jpg', 'png', 'gif'].includes(suffix)
-      let isDoc = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'].includes(suffix)
+      let isDoc = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf'].includes(suffix)
       let isPdf = suffix === 'pdf'
       let isVideo = suffix === 'mp4' || suffix === 'webm'
       let isAudio = ['mp3', 'wav'].includes(suffix)
@@ -486,14 +486,14 @@ export default {
         abilityDetail.targetName = this.reviewData.targetName
       }
       if (this.mode === 'edit') {
-        this.curTaskIndexArr = abilityDetail.stds.map((i, index) => abilityDetail.uploads[index] ? Math.max(i.task.findIndex(j => j.id === abilityDetail.uploads[index].taskid),0) : 0)
+        this.curTaskIndexArr = abilityDetail.stds.map((i, index) => abilityDetail.uploads[index] ? Math.max(i.task.findIndex(j => j.id === abilityDetail.uploads[index].taskid), 0) : 0)
       }
       return abilityDetail
     },
     /* 根据类型换取ICON图标 */
     getTypeIcon(file) {
       let suffix = file.name.split('.')[file.name.split('.').length - 1].toLowerCase()
-      if (['jpg', 'png', 'gif','webp'].includes(suffix)) {
+      if (['jpg', 'png', 'gif', 'webp'].includes(suffix)) {
         return require('../../assets/icon/pic50.png')
       }
       if (['doc', 'docx'].includes(suffix)) {

+ 23 - 18
TEAMModelOS/ClientApp/src/view/auth/Product.vue

@@ -17,7 +17,7 @@
                         </p>
                         <p class="product-content">
                             {{item.content}}
-                            <a :href="item.more" target="_black" style="text-decoration: underline;">
+                            <a :href="item[lang]" target="_black" style="text-decoration: underline;">
                                 {{$t('auth.learnMore')}}
                             </a>
                         </p>
@@ -144,6 +144,9 @@
                     <FormItem :label="$t('auth.ctFmText7')" prop="mobile">
                         <Input v-model="contact.mobile" type="number" :placeholder="$t('auth.ctFmText8')"></Input>
                     </FormItem>
+                    <FormItem :label="$t('auth.ctFmText23')" prop="email">
+                        <Input v-model="contact.email" :placeholder="$t('auth.ctFmText24')"></Input>
+                    </FormItem>
                     <!-- 不需要地区 -->
                     <!-- <FormItem :label="$t('auth.ctFmText12')" prop="address">
                         <BaseAreaPicker ref="areaPicker" v-if="isChinaSite"></BaseAreaPicker>
@@ -221,7 +224,11 @@ export default {
                 ],
                 mobile: [
                     { required: true, message: this.$t('auth.ctFmText10'), trigger: 'change' }
-                ]
+                ],
+                email: [
+                    { required: true, message: this.$t('auth.ctFmText24'), trigger: 'blur' },
+                    { type: 'email', message: this.$t('auth.ctFmText25'), trigger: 'blur' }
+                ],
             },
             contact: {
                 name: this.$store.state.userInfo.name,
@@ -245,7 +252,9 @@ export default {
                     content: this.$t('auth.content1'),
                     isPay: 0,
                     prodCode: 'YMPCVCIM',
-                    more: 'https://www.habook.com.cn/product.php?act=view&id=29'
+                    'zh-cn': 'https://www.habook.com.cn/product.php?act=view&id=28',
+                    'zh-tw': 'https://www.habook.com/zh-tw/cloud.php?act=view&id=9',
+                    'en-us': 'https://www.habook.com/en/cloud.php?act=view&id=9'
                 },
                 {
                     name: this.$t('auth.module2'),
@@ -255,7 +264,9 @@ export default {
                     content: this.$t('auth.content2'),
                     isPay: 0,
                     prodCode: 'VABAJ6NV',
-                    more: 'https://www.habook.com.cn/product.php?act=view&id=30'
+                    'zh-cn': 'https://www.habook.com.cn/product.php?act=view&id=30',
+                    'zh-tw': 'https://www.habook.com/zh-tw/cloud.php?act=view&id=8',
+                    'en-us': 'https://www.habook.com/en/cloud.php?act=view&id=8'
                 },
                 {
                     name: this.$t('auth.module3'),
@@ -265,7 +276,9 @@ export default {
                     content: this.$t('auth.content3'),
                     isPay: 0,
                     prodCode: 'Sokrates',
-                    more: 'https://www.habook.com.cn/cloud.php?act=view&id=21'
+                    'zh-cn': 'https://www.habook.com.cn/cloud.php?act=view&id=22',
+                    'zh-tw': 'https://www.habook.com/zh-tw/product.php?act=view&id=37',
+                    'en-us': 'https://www.habook.com/en/product.php?act=view&id=37'
                 }
             ]
         }
@@ -283,6 +296,10 @@ export default {
             } else {
                 return 0
             }
+        },
+        lang() {
+            let curLang = localStorage.getItem('local') || 'zh-cn'
+            return curLang
         }
     },
     methods: {
@@ -309,6 +326,7 @@ export default {
                         tmdname: this.$store.state.userInfo.name,
                         tmdid: this.$store.state.userInfo.TEAMModelId,
                         gender: this.contact.sex,
+                        email: this.contact.email,
                         cellphone: this.contact.mobile,
                         content: this.contact.content.join(',')
                     }
@@ -331,19 +349,6 @@ export default {
         toContact(isPay) {
             if (!isPay) {
                 this.formStatus = true
-                return
-                let urls = {
-                    en: 'https://www.habook.com/en/contact_us.php',
-                    tw: 'https://www.habook.com/zh-tw/contact_us.php',
-                    cn: 'https://www.habook.com.cn/contact_us.php'
-                }
-                let lang = localStorage.getItem('local') || 'zh-cn'
-                for (let key in urls) {
-                    if (lang.includes(key)) {
-                        window.open(/^(http:|https:)/i.test(urls[key]) ? urls[key] : "http://" + urls[key])
-                        break
-                    }
-                }
             }
         },
         toTeacherMgt() {

+ 3 - 3
TEAMModelOS/ClientApp/src/view/classmgt/CreateNotice.vue

@@ -93,9 +93,10 @@ export default {
             console.log(this.noticeDate)
             console.log(date)
             if (date.length == 2) {
-                this.notifyInfo.startTime = new Date(date[0]).getTime()
-                this.notifyInfo.endTime = new Date(date[1]).getTime()
+                this.notifyInfo.startTime = new Date(date[0] + " 00:00").getTime()
+                this.notifyInfo.endTime = new Date(date[1] + " 23:59").getTime()
             }
+            console.log(this.notifyInfo)
         },
         //初始化富文本编辑器
         initEditor() {
@@ -186,7 +187,6 @@ export default {
         // this.initEditor()
     },
     created() {
-        this.findClass()
         let routeData = this.$route.params
         //编辑公告
         if (routeData.notice) {

+ 15 - 9
TEAMModelOS/ClientApp/src/view/classrecord/eventchart/Exam.vue

@@ -1,7 +1,11 @@
 <template>
     <div class="exam-wrap">
         <TeacherClient></TeacherClient>
-        <div class="exam-info" v-if="!examDetaiInfo" @click="getExamInfo">
+        <div class="exam-info" v-if="!examInfo.ExamId" style="background: #fff7e6;border-color: #ffd591;color:#fa8c16">
+            <Icon type="md-podium" style="margin-right:5px" />
+            {{$t('cusMgt.rcd.oldHT')}}
+        </div>
+        <div class="exam-info" v-else-if="!examDetaiInfo" @click="getExamInfo">
             <Icon type="md-podium" style="margin-right:5px" />
             {{$t('cusMgt.rcd.evt2')}}
         </div>
@@ -10,6 +14,7 @@
             <ExamQu :quData="correctData[0] ? correctData[0].data : []" style="margin-right:50px"></ExamQu>
             <ExamTable :examInfo="examDetaiInfo" :recordInfo="recordInfo"></ExamTable>
         </div>
+
     </div>
 </template>
 <script>
@@ -40,7 +45,7 @@ export default {
             simpleData: {},
             examDetaiInfo: undefined,
             paperQuInfo: [],
-            correctData:[]
+            correctData: []
         }
     },
     methods: {
@@ -130,6 +135,7 @@ export default {
             }
         },
         getExamInfo() {
+            if (!this.examInfo.ExamId) return
             let requestData = {
                 id: this.examInfo.ExamId,
                 code: `Exam-${this.$store.state.userInfo.TEAMModelId}` //课中评测统一记录的是教师id,不用根据课堂记录scope处理
@@ -280,12 +286,12 @@ export default {
             }
         },
     },
-    watch:{
-        examInfo:{
-            deep:true,
-            immediate:true,
-            handler(n,o){
-                if(n && n.ExamId){
+    watch: {
+        examInfo: {
+            deep: true,
+            immediate: true,
+            handler(n, o) {
+                if (n && n.ExamId) {
                     this.getExamInfo()
                 }
             }
@@ -308,7 +314,7 @@ export default {
     user-select: none;
     cursor: pointer;
 }
-.exam-chart-wrap{
+.exam-chart-wrap {
     display: flex;
     flex-wrap: wrap;
 }

+ 1 - 1
TEAMModelOS/ClientApp/src/view/classrecord/eventchart/ExamTable.vue

@@ -284,7 +284,7 @@ export default {
             let requestData = {
                 id: this.examInfo.id,
                 code: this.recordInfo.scope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,
-                subjectId: this.recordInfo.subjectId,
+                subjectId: this.recordInfo.scope == 'school' ? this.recordInfo.subjectId : this.recordInfo.courseId,
                 classId: this.recordInfo.groupIds[0],
             };
             this.$api.learnActivity.FindAllStudent(requestData).then(

+ 3 - 0
TEAMModelOS/ClientApp/src/view/homepage/HomePage.vue

@@ -525,6 +525,9 @@ export default {
                         let sasInfo = item.scope == 'school' ? schoolSasInfo : privateSasInfo
                         item.poster = `${sasInfo.url}/${sasInfo.name}/records/${item.id}/Record/CoverImage.jpg${sasInfo.sas}`
                     })
+                    this.recentRcdList.sort((a, b) => {
+                        return b.startTime - a.startTime
+                    })
                     console.log(this.recentRcdList)
                 },
                 err => {

+ 2 - 1
TEAMModelOS/ClientApp/src/view/homepage/RcdPoster.vue

@@ -42,6 +42,7 @@ export default {
 </script>
 <style scoped lang="less">
 .rcd-poster-img {
-    width: 100%;
+    max-width: 100%;
+    max-height: 100%;
 }
 </style>

+ 13 - 5
TEAMModelOS/ClientApp/src/view/mycourse/MyCourse.vue

@@ -3,7 +3,9 @@
         <!-- 顶部课程筛选区域 -->
         <div class="my-course-header">
             <div class="course-type" v-show="isShowTypeFilter">
-                <span class="filter-label">来源:</span>
+                <span class="filter-label">
+                    {{$t('cusMgt.cusSource')}}
+                </span>
                 <RadioGroup v-model="listType" type="button">
                     <Radio v-for="item in cusType" :label="item.value" :key="item.value">
                         {{item.label}}
@@ -11,8 +13,12 @@
                 </RadioGroup>
             </div>
             <div :class="courseTypeClass" @mouseover="checkOverflow" @mouseleave="removeOverflow">
-                <span class="filter-label">课程:</span>
-                <span v-show="!courseListShow.length">暂无课程</span>
+                <span class="filter-label">
+                    {{$t('home.course')}}
+                </span>
+                <span v-show="!courseListShow.length">
+                    {{$t('cusMgt.noScCus')}}
+                </span>
                 <RadioGroup v-model="courseId" type="button" id="course-list-box" style="width: calc(100% - 70px);">
                     <Radio v-for="item in courseListShow" :label="item.id" :key="item.id" style="margin-right:15px">
                         {{item.name}}
@@ -25,7 +31,9 @@
 
             </div>
             <div class="course-action-wrap">
-                <Button type="text" icon="md-add" @click="addCusStatus = true">新建个人课程</Button>
+                <Button type="text" icon="md-add" @click="addCusStatus = true">
+                    {{$t('cusMgt.createPrivCus')}}
+                </Button>
             </div>
         </div>
         <div class="my-course-main custom-iview-split">
@@ -275,7 +283,7 @@ export default {
             return {
                 scope: this.listType,
                 courseId: this.courseId,
-                classId: this.teaClassList[this.curClassIndex].classId || this.teaClassList[this.curClassIndex].stulist
+                classId: this.teaClassList[this.curClassIndex]?.classId || this.teaClassList[this.curClassIndex]?.stulist
             }
         },
         students() {

+ 2 - 2
TEAMModelOS/ClientApp/src/view/mycourse/notice/Create.vue

@@ -120,8 +120,8 @@ export default {
     methods: {
         getTimestamp(date) {
             if (date.length == 2) {
-                this.notifyInfo.startTime = new Date(date[0]).getTime()
-                this.notifyInfo.endTime = new Date(date[1]).getTime()
+                this.notifyInfo.startTime = new Date(date[0] + " 00:00").getTime()
+                this.notifyInfo.endTime = new Date(date[1] + " 23:59").getTime()
             }
         },
         //初始化富文本编辑器

+ 50 - 22
TEAMModelOS/ClientApp/src/view/mycourse/student/Student.vue

@@ -1,28 +1,56 @@
 <template>
     <div class="cus-student-contianer">
         <div class="stu-action-wrap common-save-btn">
-            <span v-if="stuList && stuList.scope == 'private'" class="action-item" @click="delStudents">
-                <Icon type="md-trash" size="16" />
-                {{$t('cusMgt.delStu')}}
-            </span>
-            <span v-if="stuList && stuList.scope == 'private'" v-show="$store.state.userInfo.hasSchool" class="action-item" @click="addStuStatus = true">
-                <Icon type="md-add" size="16" />
-                {{$t('cusMgt.addStu')}}
-            </span>
-            <span v-if="stuList && stuList.scope == 'private'" class="action-item" @click="setIrsStatus = true">
-                <Icon type="md-settings" size="16" />
-                {{$t('cusMgt.editStu')}}
-            </span>
-            <Button icon="md-download" class="save-btn action-item" @click="generateQrcodes" :loading="btnLoading">
-                {{$t('schoolBaseInfo.exportQrCode')}}
-            </Button>
-            <Button icon="md-download" class="save-btn action-item" @click="generatePDF" :loading="pdfLoading">
-                {{$t('schoolBaseInfo.exportList')}}
-            </Button>
-            <span class="action-item" @click="exportStudents">
-                <Icon type="md-download" size="16" />
-                {{$t('cusMgt.exportStu')}}
-            </span>
+            <Dropdown style="margin-top:5px;margin-right:8px">
+                <a href="javascript:void(0)">
+                    {{$t('cusMgt.moreFn')}}
+                    <Icon type="ios-arrow-down"></Icon>
+                </a>
+                <DropdownMenu slot="list">
+                    <DropdownItem>
+                        <!-- <Button icon="md-download" class="save-btn action-item" @click="generateQrcodes" :loading="btnLoading">
+                            {{$t('schoolBaseInfo.exportQrCode')}}
+                        </Button> -->
+                        <span @click="generateQrcodes">
+                            <Icon type="md-download" size="16" />
+                            {{$t('schoolBaseInfo.exportQrCode')}}
+                        </span>
+                    </DropdownItem>
+                    <DropdownItem>
+                        <!-- <Button icon="md-download" class="save-btn action-item" @click="generatePDF" :loading="pdfLoading">
+                            {{$t('schoolBaseInfo.exportList')}}
+                        </Button> -->
+                        <span @click="generatePDF">
+                            <Icon type="md-download" size="16" />
+                            {{$t('schoolBaseInfo.exportList')}}
+                        </span>
+                    </DropdownItem>
+                    <DropdownItem>
+                        <span class="action-item" @click="exportStudents">
+                            <Icon type="md-download" size="16" />
+                            {{$t('cusMgt.exportStu')}}
+                        </span>
+                    </DropdownItem>
+                    <DropdownItem v-if="stuList && stuList.scope == 'private'" class="action-item">
+                        <span @click="setIrsStatus = true">
+                            <Icon type="md-settings" size="16" />
+                            {{$t('cusMgt.editStu')}}
+                        </span>
+                    </DropdownItem>
+                    <DropdownItem v-if="stuList && stuList.scope == 'private'" v-show="$store.state.userInfo.hasSchool">
+                        <span class="action-item" @click="addStuStatus = true">
+                            <Icon type="md-add" size="16" />
+                            {{$t('cusMgt.addStu')}}
+                        </span>
+                    </DropdownItem>
+                    <DropdownItem v-if="stuList && stuList.scope == 'private'">
+                        <span class="action-item" @click="delStudents">
+                            <Icon type="md-trash" size="16" />
+                            {{$t('cusMgt.delStu')}}
+                        </span>
+                    </DropdownItem>
+                </DropdownMenu>
+            </Dropdown>
         </div>
         <vuescroll style="height:100%;">
             <Alert @on-close="isClose = true" v-show="!isClose" show-icon type="warning" style="margin-bottom:0px" closable>

+ 2 - 2
TEAMModelOS/ClientApp/src/view/notify/CreateNotify.vue

@@ -77,8 +77,8 @@ export default {
             console.log(this.noticeDate)
             console.log(date)
             if (date.length == 2) {
-                this.notifyInfo.startTime = new Date(date[0]).getTime()
-                this.notifyInfo.endTime = new Date(date[1]).getTime()
+                this.notifyInfo.startTime = new Date(date[0] + " 00:00").getTime()
+                this.notifyInfo.endTime = new Date(date[1] + " 23:59").getTime()
             }
         },
         //初始化富文本编辑器

+ 1 - 2
TEAMModelOS/TEAMModelOS.csproj

@@ -10,7 +10,6 @@
   </ItemGroup>
   <ItemGroup>
     <None Remove="ClientApp\src\static\BaseDataDefault.json" />
-    <None Remove="libwkhtmltox.dll" />
   </ItemGroup>
   <ItemGroup>
     <Folder Include="Controllers\Third\Xkw\Hmac\" />
@@ -44,7 +43,7 @@
     <AssemblyVersion>5.2205.25.1</AssemblyVersion>
     <FileVersion>5.2205.25.1</FileVersion>
     <Description>TEAMModelOS(IES5)</Description>
-    <PackageReleaseNotes>IES版本说明版本标记5.2205.25.1</PackageReleaseNotes>
+    <PackageReleaseNotes>IES版本说明版本标记5.2205.25.1,RC切换Master标记</PackageReleaseNotes>
     <PackageId>TEAMModelOS</PackageId>
     <Authors>teammodel</Authors>
     <Company>醍摩豆(成都)信息技术有限公司</Company>