Explorar o código

Merge branch 'develop' of http://52.130.252.100:10000/TEAMMODEL/TEAMModelOS into develop

zhouj1203@hotmail.com hai 1 ano
pai
achega
1fe50f8b83
Modificáronse 26 ficheiros con 623 adicións e 407 borrados
  1. 24 8
      TEAMModelBI/ClientApp/src/view/userInquire/details.vue
  2. 106 102
      TEAMModelBI/ClientApp/src/view/userInquire/ies.vue
  3. 4 3
      TEAMModelBI/ClientApp/src/view/userInquire/index.vue
  4. 0 6
      TEAMModelBI/ClientApp/src/view/userInquire/score.vue
  5. 15 13
      TEAMModelBI/ClientApp/src/view/userInquire/socrates.vue
  6. 77 67
      TEAMModelBI/ClientApp/src/view/userInquire/ticket.vue
  7. 20 42
      TEAMModelBI/ClientApp/src/view/userInquire/userdetail.vue
  8. 54 1
      TEAMModelOS.SDK/Models/Cosmos/Common/Activity.cs
  9. 1 1
      TEAMModelOS.SDK/Models/Cosmos/Normal/TMDOrder.cs
  10. 1 1
      TEAMModelOS.SDK/Models/Service/Common/TeacherService.cs
  11. 1 0
      TEAMModelOS/ClientApp/public/lang/en-US.js
  12. 1 0
      TEAMModelOS/ClientApp/public/lang/zh-CN.js
  13. 1 0
      TEAMModelOS/ClientApp/public/lang/zh-TW.js
  14. 10 10
      TEAMModelOS/ClientApp/src/view/areaMgmt/AreaLayout.vue
  15. 160 123
      TEAMModelOS/ClientApp/src/view/coursemgt/components/ImportTask.vue
  16. 5 2
      TEAMModelOS/ClientApp/src/view/evaluation/bank/index.vue
  17. 4 1
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseMultiple.vue
  18. 4 1
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseSingle.vue
  19. 8 4
      TEAMModelOS/ClientApp/src/view/iot/areaiot.vue
  20. 8 3
      TEAMModelOS/ClientApp/src/view/iot/schooliot.vue
  21. 2 2
      TEAMModelOS/ClientApp/src/view/login/page/Student.vue
  22. 18 1
      TEAMModelOS/Controllers/Common/ActivityController.cs
  23. 5 5
      TEAMModelOS/Controllers/System/WeChatPayController.cs
  24. 84 7
      TEAMModelOS/Controllers/Third/Sc/ScDataPushController.cs
  25. 1 1
      TEAMModelOS/JsonFile/Core/mail.html
  26. 9 3
      TEAMModelOS/Startup.cs

+ 24 - 8
TEAMModelBI/ClientApp/src/view/userInquire/details.vue

@@ -177,11 +177,16 @@
             </div>
         </div>
         <!--产品页面end-->
+        <!--back-->
+        <div class="back-btns">
+            <el-button type="info" :icon="ArrowLeft" size="small" @click="backClick">返回搜索</el-button>
+        </div>
+        <!--back end-->
     </div>
 </template>
 <script setup>
-import { ref, getCurrentInstance, watch, h, nextTick,onMounted,defineProps } from 'vue'
-import { Iphone,More,MoreFilled } from '@element-plus/icons'
+import { ref, getCurrentInstance, watch, h, nextTick,onMounted,defineProps,defineEmits } from 'vue'
+import { Iphone,More,MoreFilled,ArrowLeft } from '@element-plus/icons'
 import commonHeatmapVue from '../../components/echarts/commonHeatmap.vue'
 import commonGaugeVue from '../../components/echarts/commonGauge.vue'
 import Hiteach from './hiteach.vue'
@@ -207,7 +212,7 @@ let userdata = ref([
     { id: 3, icon: '#icon-dibudaohanglan-', value: '', title: '',key:'school',correlation:false,check:true,hint:'学校'},
     { id: 4, icon: '#icon-youxiang', value: '', title: '', key: 'email', check: true, hint: '邮箱' },
     { id: 5, icon: '#icon-weizhi', value: '', title: '',key:'local',check:false ,hint:'地区位置'},
-    { id: 6, icon: '#icon-shijian2', value: '2023-04-23', title: '', key: 'time', check: false ,hint:'上次登录时间' },
+    { id: 6, icon: '#icon-shijian2', value: '0', title: '', key: 'time', check: false ,hint:'上次登录时间' },
 ])
 let productdata = ref([
     { id: 1, title: 'HiTeach', value:0,key:'HiTeach',state: false },
@@ -513,6 +518,11 @@ let powerList=ref([])
 const handleChildEvent = (payload) => {
     userdetailState.value=false
 }
+const emits = defineEmits(['parentClick']) 
+const backClick = () => {
+    console.log('back init')
+        emits('parentClick','default') // 使用方式和 vue2 this.$emit 一样
+}
 function initdata() {
     let transmitData = detailsData.value[0]
     console.log(transmitData,'数据')
@@ -528,7 +538,7 @@ function initdata() {
     //产品使用及安装情况
     let {login}=transmitData
     let logintimes = login.length >0 ? login.sort(function(a,b){return b.time-a.time}):'无'
-    userdata.value[5].value=proxy.$common.timestampToTime(logintimes[0].time,'all')
+    logintimes !=='无' ?  userdata.value[5].value=proxy.$common.timestampToTime(logintimes[0].time,'all'):userdata.value[5].value='暂无'
     if(login.length >0){
        login.forEach(item => {
          let typename=item.product
@@ -571,12 +581,12 @@ function initdata() {
         let days = Math.floor(timeDifference / (24 * 60 * 60 ));
         console.log(days,'天数')
         item.intervalTime=days
-        item.startDateText=proxy.$common.timestampToTime(item.startDate)
-        item.endDateText=proxy.$common.timestampToTime(item.endDate)
+        item.startDateText=item.startDateText ? proxy.$common.timestampToTime(item.startDate):0
+        item.endDateText= item.endDateText? proxy.$common.timestampToTime(item.endDate):0
         powerList.value.push(item)  
     })
     //处理权益内 附加功能(HITeach附加 CC权限)
-    let hiteachData=benefits.hiteach; let ccData=benefits.hiteachcc
+    let hiteachData=benefits.hiteach !==null ?benefits.hiteach:[] ; let ccData=benefits.hiteachcc !==null  ?benefits.hiteachcc:[]
     if(hiteachData.length >0){
         hiteachData.forEach((item)=>{
             let funcKey=item.func;let startTime=proxy.$common.timestampToTime(item.get);let endTime=proxy.$common.timestampToTime(item.exp)
@@ -585,7 +595,7 @@ function initdata() {
             })
         })
     }
-    if(ccData.length >0){
+    if(ccData.length >0 ){
         ccData.forEach((itemA)=>{
             let funcKey=itemA.func;let startTime=proxy.$common.timestampToTime(itemA.get);let endTime=proxy.$common.timestampToTime(itemA.exp)
             subjoinData.value.hiteachCC.forEach((itemc)=>{
@@ -621,6 +631,7 @@ onMounted(() => {
     border-radius: 5px;
     /* overflow: hidden;
     overflow-y: auto; */
+    position: relative;
 }
 .topbox{
     width:100%;
@@ -1026,6 +1037,11 @@ onMounted(() => {
 ::-webkit-scrollbar {
   background-color: #e6f9ff; /* 设置背景颜色 */
 }
+.back-btns{
+    position:absolute;
+    right:5px;
+    top:0px;
+}
 </style>
 <style>
 .inquirebox-details .el-divider{

+ 106 - 102
TEAMModelBI/ClientApp/src/view/userInquire/ies.vue

@@ -65,16 +65,15 @@
             </div>
         <el-divider />
             <div class="ies-flex">
-                <!-- <div class="schools-item" v-for="item in schooldata" :key="item.code">
-                <div class="schools-item-name">{{item.name}}<span class="school-item-edition">专业版</span></div>
-                <p class="schools-item-location">{{item.code}} | {{item.location}}</p>
-                <div class="schools-item-charge">负责课程数<span class="schools-item-charge-num">{{item.class}}</span></div>
-                <div class="schools-item-size">
-                    <p class="schools-item-size-title">学校空间状态</p>
-                    <span class="schools-item-size-text">{{item.totalsize}}GB 中的 {{item.occupy}}GB (20%)</span>
-                </div> -->
-            <!-- </div> -->
-            <bars :barData="echartsBar"></bars>
+                <div class="ies-flex-echart">
+                    <Pies :piesData="echartsBar"></Pies>
+                </div>
+                <div class="ies-flex-text">
+                    <p>总计:</p>
+                    <p v-for="item in personageSize" :key="item.key">
+                        <span>{{item.title}}:</span><span class="sizenum-text">{{item.value}}</span> GB
+                    </p>
+                </div>
             </div>
             <div class="dialog-school">
                 <el-dialog v-model="allschoolState" title="加入学校列表" width="50%" :before-close="handleClose">
@@ -121,9 +120,11 @@
  import { ArrowRight } from '@element-plus/icons'
  import * as echarts from 'echarts'
  import bars from '@/components/echarts/commonBar.vue'
+ import Pies from './echarts/pie.vue'
  let props = defineProps({
     iesdata: Object,
 })
+let { proxy } = getCurrentInstance()
  let relevancedata = ref([
       { title: '资源数', icon: '#icon-anli', value: 0, key: 'material' },
       { title: '试题数', icon: '#icon-tiku', value: 0, key: 'question' },
@@ -148,108 +149,74 @@
       {name:'南京特殊教育师范学院',code:'ntsjsy',location:'中国',class:15,totalsize:300,occupy:75}
  ])
  let allschoolList=ref([])
+ let personageSize=ref([
+    {title:'总大小',value:0,key:'total'},
+    {title:'已使用',value:0,key:'used'},
+    {title:'已剩余',value:0,key:'residue'},
+    {title:'学校分配空间',value:0,key:'allocation'}
+ ])
  let echartsBar=ref({
-    tooltip: {
-        trigger: 'axis',
-        axisPointer: {
-            type: 'shadow'
+    title: {
+        text: 'IES个人空间',
+        x: 'center',
+        y: 'center',
+        textStyle: {
+            fontWeight: 'normal',
+            color: '#0580f2',
+            fontSize: '20'
         }
     },
-    grid: {
-        // top: '15%',
-        // right: '3%',
-        // left: '5%',
-        bottom: '8%'
+    color: ['rgba(176, 212, 251, 1)'], 
+    // legend: {
+    //     show: true,
+    //     itemGap: 12,
+    //     data: ['01', '02']
+    // },
+    "tooltip": {
+        "trigger": 'item',
+        "formatter": "{b} : ({d}%)"
     },
-    xAxis: [{
-        data: ['合作','互动','任务','差异化','测验'],
-        axisLine: {
-            lineStyle: {
-                color: '#333'
-            }
-        },
-        axisLabel: {
-            // margin: 10,
-            color: '#333',
-            textStyle: {
-                fontSize: 10
-            },
-        },
-    }],
-    yAxis: [{
-        name: "课堂型态",
-        nameTextStyle: {
-            color: '#0177d4',
-            fontSize: 12
-        },
-        axisLine: {
-            show:true,
-            lineStyle: {
-                color: '#0177d4',
-                width:'1'
-            }
-        },
-        axisLabel: {
-            color: '#0177d4',
-            fontSize: 16
-        },
-        splitLine: {
-            show:false,
-            lineStyle: {
-                color: '#0177d4'
-            }
-        },
-    }],
     series: [{
-        type: 'bar',
-        data: [300, 450, 770, 203],
-        barWidth: '16px',
-        barBorderRadius: 5,
-        itemStyle:{
-            normal:{
-                color:new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
-                    offset: 0,
-                    color: '#00b0ff'
-                }, {
-                    offset: 0.8,
-                    color: '#7052f4'
-                    }], false),
-               barBorderRadius: 5,
+        type: 'pie',
+        clockWise: true,
+        radius: ['55%', '80%'],
+        itemStyle: {
+            normal: {
+                label: {
+                    show: false
+                },
+                labelLine: {
+                    show: false
+                }
             }
         },
-        label: {
-            normal: {
-                show: true,
-                lineHeight: 30,
-                width: 80,
-                height: 30,
-                backgroundColor: 'rgba(0,160,221,0.1)',
-                borderRadius: 200,
-                position: ['-8', '-60'],
-                distance: 1,
-                formatter: [
-                    '    {d|●}',
-                    ' {a|{c}}     \n',
-                    '    {b|}'
-                ].join(''),
-                rich: {
-                    d: {
-                        color: '#3CDDCF',
-                    },
-                    a: {
-                        color: '#00b0ff',
-                        align: 'center',
+        hoverAnimation: true, 
+        data: [{
+            value: 80,
+            name: '已使用',
+            itemStyle: {
+                normal: {
+                    color: { // 完成的圆环的颜色
+                        colorStops: [{
+                            offset: 0,
+                            color: '#00cefc' // 0% 处的颜色
+                        }, {
+                            offset: 1,
+                            color: '#367bec' // 100% 处的颜色
+                        }]
                     },
-                    b: {
-                        width: 1,
-                        height: 30,
-                        borderWidth: 1,
-                        borderColor: '#234e6c',
-                        align: 'left'
+                    label: {
+                        show: false
                     },
-                }
+                    labelLine: {
+                        show: false
+                    }
+                } 
             }
-        }
+        }, {
+            name: '已剩余',
+            value: 20
+        }]
     }]
  })
  function initdatas(){
@@ -284,8 +251,26 @@
         items.size.percentage=Math.round(((items.size.used/ items.size.total).toFixed(2))*100)
         allschoolList.value.push(items)
     })
+    //处理空间大小
+    let {usedSize,surplusSize,totalSize,teachSize}=props.iesdata
+    let transitionUsed=usedSize ?bytesToGB(usedSize):0
+    let transitionSuplus=surplusSize ? bytesToGB(surplusSize):0
+    let transitionTotal=totalSize ? bytesToGB(totalSize):0
+    let transitionTeach=teachSize ? bytesToGB(teachSize):0
+    console.log(transitionUsed,transitionSuplus,transitionTotal,transitionTeach,'各个大小')
+    // echartsBar.value.series[0].data[0].value = (usedSize/totalSize).toFixed(2)*100
+    echartsBar.value.series[0].data[0].value= transitionUsed !==0 ? Math.round((transitionUsed/transitionTotal).toFixed(2)*100):0
+    echartsBar.value.series[0].data[1].value=100-Number(echartsBar.value.series[0].data[0].value)
+    personageSize.value[0].value=transitionTotal
+    personageSize.value[1].value=transitionUsed
+    personageSize.value[2].value=transitionSuplus
+    personageSize.value[3].value=transitionTeach
     console.log(allschoolList.value,'list')
  }
+ function bytesToGB(bytes) {
+  const gb = bytes / (1024 * 1024 * 1024);
+  return gb.toFixed(0); // 将结果保留两位小数
+}
  onMounted(() => {
     initdatas()
 })
@@ -331,6 +316,21 @@
     justify-content: space-between;
     overflow: hidden;
     overflow-x: auto; */
+    display: flex;
+    align-items: center;
+ }
+ .ies-flex-echart{
+    width:70%;
+    height:100%;
+ }
+ .ies-flex-text{
+    width:30%;
+    text-align: left;
+    padding-left: 1%;
+    line-height: 40px;
+ }
+ .ies-flex-text p{
+    margin-bottom: 5px;
  }
  .schools-item{
     flex: 0 0 40%;
@@ -539,6 +539,10 @@
  .fontsize{
     font-size:12px;
  }
+ .sizenum-text{
+    font-weight: bold;
+    color:#409EFF;
+ }
  </style>
 <style>
 .dialog-school .el-dialog__body{

+ 4 - 3
TEAMModelBI/ClientApp/src/view/userInquire/index.vue

@@ -21,7 +21,7 @@
                 </template>
                 </el-input>
             </div>
-            <div class="recordbox" v-if="selecttypes==='precise'">
+            <!-- <div class="recordbox" v-if="selecttypes==='precise'">
                 <p>搜索记录:</p>
                 <div class="recordbox-item">
                     <el-tag v-for="tag in tags" :key="tag.name" class="mx-1" closable :type="tag.type">
@@ -31,11 +31,11 @@
             </div>
             <div class="recordbox" v-else="selecttypes ==='batch'">
                 <p>搜索结果:</p>
-            </div>
+            </div> -->
         </div>
     </div>
     <div class="inquirebox-details" v-else-if="pageShow ==='details'">
-        <Detailsbox :searchdata="searchResult"></Detailsbox>
+        <Detailsbox :searchdata="searchResult" @parentClick="backClicks"></Detailsbox>
     </div>
 </template>
 <script setup>
@@ -56,6 +56,7 @@ let searchvalue=ref('')
 let selecttypes = ref('precise')
 let searchResult=ref()
 let searchLoading=ref(false)
+const backClicks=()=>{pageShow.value='default'}
 function seachSole(datavalue) {
     if(!searchvalue.value){
         ElMessage.info('请输入手机号码/ 醍魔豆账号 进行搜索!')

+ 0 - 6
TEAMModelBI/ClientApp/src/view/userInquire/score.vue

@@ -121,12 +121,6 @@ let scoredetail = ref({
         {type:'add',typename:'系统添加',value:'+2000',time:'2023/05/23 15:23'},
     ]
 })
-let tdatas = ref([
-    { title: '总时长(分)', value: 'XXXX', key: 'times' },
-    { title: '学生人次', value: 'XXXX', key: 'stundennum' },
-    { title: '互动次数', value: 'XXXX', key: 'interact' },
-    { title: '学生学习总时长', value: 'XXXX', key: 'studentime' },
-])
 function initdatas(){
     console.log(props,'SGLD')
     scoredata.value[0].value=Number(props.pointsdatas.points)-Number(props.pointsdatas.balance)   

+ 15 - 13
TEAMModelBI/ClientApp/src/view/userInquire/socrates.vue

@@ -257,10 +257,10 @@ let hiteachDatas=ref({
         }]
  })
  let tdatas = ref([
-    { title: '总时长(分)', values: 'XXXX', key: 'times' },
-    { title: '学生人次', values: 'XXXX', key: 'stundennum' },
-    { title: '互动次数', values: 'XXXX', key: 'interact' },
-    { title: '学生学习总时长', values: 'XXXX', key: 'studentime' },
+    { title: '总时长(分)', values: '0', key: 'times' },
+    { title: '学生人次', values: '0', key: 'stundennum' },
+    { title: '互动次数', values: '0', key: 'interact' },
+    { title: '学生学习总时长', values: '0', key: 'studentime' },
 ])
 let buttonSelect = ref([
     { name: '周', value: 'week', click: true },
@@ -368,16 +368,18 @@ function initdatas(){
     console.log(props,'苏格拉底')
     let {hiteach_data,user_channels}=props.sokratesdatas
     //处理预设学校
-    user_channels.benefits.t_data &&  user_channels.default_channel.school_name && user_channels.default_channel.school_code ?
-    (presupposed.value.data.benefits=user_channels.benefits,
-    presupposed.value.data.default_channel=user_channels.default_channel,
-    presupposed.value.data.general_observation=user_channels.general_observation,
-    presupposed.value.state=true)
-    :presupposed.value.state=false
+    if(user_channels !==null){
+        user_channels.benefits.t_data &&  user_channels.default_channel.school_name && user_channels.default_channel.school_code ?
+        (presupposed.value.data.benefits=user_channels.benefits,
+        presupposed.value.data.default_channel=user_channels.default_channel,
+        presupposed.value.data.general_observation=user_channels.general_observation,
+        presupposed.value.state=true)
+        :presupposed.value.state=false
+    }
     //处理total数据
-    primary.value[0].value=hiteach_data.total.t_data
-    primary.value[1].value=hiteach_data.total.t_green
-    primary.value[2].value=hiteach_data.total.double_green_light
+    primary.value[0].value=hiteach_data.total.t_data ? hiteach_data.total.t_data:0
+    primary.value[1].value=hiteach_data.total.t_green ? hiteach_data.total.t_green:0
+    primary.value[2].value=hiteach_data.total.double_green_light ? hiteach_data.total.double_green_light:0
     // primary.value[3].value=hiteach_data.total.
 
     auxiliary.value[0].value='XXX'

+ 77 - 67
TEAMModelBI/ClientApp/src/view/userInquire/ticket.vue

@@ -11,83 +11,88 @@
         </div>
         <el-divider />
         <div class="ticket-detail">
-            <el-tabs :tab-position="tabPosition" style="height: 40vh" class="demo-tabs">
-                <el-tab-pane label="已使用">
-                    <div class="ticket-total">
-                        <div :class="[item.type ==='use' ? 'usebox':'','ticket-total-item']" v-for="item in ticketlist" :key="item.code">
-                            <div class="ticket-total-item-title">
-                                <div class="ticket-subhead">兑换券</div>
-                                <div class="ticket-code">{{item.code}}</div>
-                            </div>
-                            <div class="ticket-total-item-content">
-                                <p class="ticket-total-title">授权</p>
-                                <!-- <div class="ticket-total-item-scope">
-                                    {{item.scope}}
-                                </div>
-                                <div class="ticket-total-item-type">
-                                    {{item.source}}
-                                </div> -->
-                                <div class="ticket-total-item-time">
-                                    于{{item.exchangeTime}} 使用
+            <template v-if="ticketlist.length !==0">
+                <el-tabs :tab-position="tabPosition" style="height: 40vh" class="demo-tabs">
+                    <el-tab-pane label="已使用">
+                        <div class="ticket-total">
+                            <div :class="[item.type ==='use' ? 'usebox':'','ticket-total-item']" v-for="item in ticketlist" :key="item.code">
+                                <div class="ticket-total-item-title">
+                                    <div class="ticket-subhead">兑换券</div>
+                                    <div class="ticket-code">{{item.code}}</div>
                                 </div>
-                                <div class="ticket-use">
-                                    <svg class="useicon" aria-hidden="true">
-                                        <use xlink:href="#icon-yishiyong"></use>
-                                    </svg>
+                                <div class="ticket-total-item-content">
+                                    <p class="ticket-total-title">授权</p>
+                                    <!-- <div class="ticket-total-item-scope">
+                                        {{item.scope}}
+                                    </div>
+                                    <div class="ticket-total-item-type">
+                                        {{item.source}}
+                                    </div> -->
+                                    <div class="ticket-total-item-time">
+                                        于{{item.exchangeTime}} 使用
+                                    </div>
+                                    <div class="ticket-use">
+                                        <svg class="useicon" aria-hidden="true">
+                                            <use xlink:href="#icon-yishiyong"></use>
+                                        </svg>
+                                    </div>
                                 </div>
                             </div>
                         </div>
-                    </div>
-                </el-tab-pane>
-                <!-- <el-tab-pane label="使用">
-                    <div class="ticket-total">
-                        <div :class="[item.type ==='use' ? 'usebox':'','ticket-total-item']" v-for="item in usedata" :key="item.code">
-                            <div class="ticket-total-item-title">
-                                <div class="ticket-subhead">兑换券</div>
-                                <div class="ticket-code">{{item.code}}</div>
-                            </div>
-                            <div class="ticket-total-item-content">
-                                <div class="ticket-total-item-scope">
-                                    {{item.scope}}
-                                </div>
-                                <div class="ticket-total-item-type">
-                                    {{item.source}}
-                                </div>
-                                <div class="ticket-total-item-usetime">
-                                    {{item.time}} 使用
+                    </el-tab-pane>
+                    <!-- <el-tab-pane label="使用">
+                        <div class="ticket-total">
+                            <div :class="[item.type ==='use' ? 'usebox':'','ticket-total-item']" v-for="item in usedata" :key="item.code">
+                                <div class="ticket-total-item-title">
+                                    <div class="ticket-subhead">兑换券</div>
+                                    <div class="ticket-code">{{item.code}}</div>
                                 </div>
-                                <div class="ticket-use">
-                                    <svg class="useicon" aria-hidden="true">
-                                        <use xlink:href="#icon-yishiyong"></use>
-                                    </svg>
+                                <div class="ticket-total-item-content">
+                                    <div class="ticket-total-item-scope">
+                                        {{item.scope}}
+                                    </div>
+                                    <div class="ticket-total-item-type">
+                                        {{item.source}}
+                                    </div>
+                                    <div class="ticket-total-item-usetime">
+                                        {{item.time}} 使用
+                                    </div>
+                                    <div class="ticket-use">
+                                        <svg class="useicon" aria-hidden="true">
+                                            <use xlink:href="#icon-yishiyong"></use>
+                                        </svg>
+                                    </div>
                                 </div>
                             </div>
                         </div>
-                    </div>
-                </el-tab-pane>
-                <el-tab-pane label="拥有">
-                    <div class="ticket-total">
-                        <div :class="[item.type ==='use' ? 'usebox':'','ticket-total-item']" v-for="item in gaindata" :key="item.code">
-                            <div class="ticket-total-item-title">
-                                <div class="ticket-subhead">兑换券</div>
-                                <div class="ticket-code">{{item.code}}</div>
-                            </div>
-                            <div class="ticket-total-item-content">
-                                <p class="ticket-total-title">授权</p>
-                                <div class="ticket-total-item-scope">
-                                    {{item.scope}}
-                                </div>
-                                <div class="ticket-total-item-type">
-                                    {{item.source}}
+                    </el-tab-pane>
+                    <el-tab-pane label="拥有">
+                        <div class="ticket-total">
+                            <div :class="[item.type ==='use' ? 'usebox':'','ticket-total-item']" v-for="item in gaindata" :key="item.code">
+                                <div class="ticket-total-item-title">
+                                    <div class="ticket-subhead">兑换券</div>
+                                    <div class="ticket-code">{{item.code}}</div>
                                 </div>
-                                <div class="ticket-total-item-time">
-                                    {{item.time}} 到期
+                                <div class="ticket-total-item-content">
+                                    <p class="ticket-total-title">授权</p>
+                                    <div class="ticket-total-item-scope">
+                                        {{item.scope}}
+                                    </div>
+                                    <div class="ticket-total-item-type">
+                                        {{item.source}}
+                                    </div>
+                                    <div class="ticket-total-item-time">
+                                        {{item.time}} 到期
+                                    </div>
                                 </div>
                             </div>
                         </div>
-                    </div>
-                </el-tab-pane> -->
-            </el-tabs>
+                    </el-tab-pane> -->
+                </el-tabs>
+            </template>
+            <template v-else>
+                <div class="not-coupons">暂无票卷相关数据</div>
+            </template>
             <div class="ticket-box">
                 票卷明细
             </div>
@@ -128,10 +133,11 @@ let gaindata = computed(() => {
     ticketdata.value[1].value=points.balance
     ticketdata.value[2].value=points.points
     //票卷
+    coupons.length !==0 ?
     coupons.forEach(item => {
         item.exchangeTime=proxy.$common.timestampToTime(item.exchange,'all')
         ticketlist.value.push(item)
-    });
+    }):''
  }
  onMounted(() => {
     inidatas()
@@ -278,7 +284,11 @@ let gaindata = computed(() => {
     position: relative;
     padding-top:25px;
 }
-
+.not-coupons{
+    font-size:16px;
+    color: #73767a;
+    line-height: 120px;
+}
 /* .usebox{
     color:rgba(255,255,255,.9) !important;
 } */

+ 20 - 42
TEAMModelBI/ClientApp/src/view/userInquire/userdetail.vue

@@ -34,6 +34,14 @@
                         </div>
                         <div v-show="userdata.countrystate">
                             <el-cascader v-model="userdata.country" :options="options" @change="handleChange" />
+                            <el-select v-model="userdata.country" class="m-2" @change="handleChange">
+                              <el-option
+                                v-for="item in options"
+                                :key="item.value"
+                                :label="item.label"
+                                :value="item.value"
+                              />
+                            </el-select>
                         </div>
                         <div class="redacticon">
                             <el-icon size="20" @click="userdata.countrystate=true"><EditPen /></el-icon>
@@ -116,48 +124,18 @@
       { name: '钉钉', icon: '#icon-dingding', state: true, key: 'dingding' },
  ])
  let options=ref( [
-  {
-    value: 'guide',
-    label: 'Guide',
-    children: [
-      {
-        value: 'disciplines',
-        label: 'Disciplines',
-        children: [
-          {
-            value: 'consistency',
-            label: 'Consistency',
-          },
-          {
-            value: 'feedback',
-            label: 'Feedback',
-          },
-          {
-            value: 'efficiency',
-            label: 'Efficiency',
-          },
-          {
-            value: 'controllability',
-            label: 'Controllability',
-          },
-        ],
-      },
-      {
-        value: 'navigation',
-        label: 'Navigation',
-        children: [
-          {
-            value: 'side nav',
-            label: 'Side Navigation',
-          },
-          {
-            value: 'top nav',
-            label: 'Top Navigation',
-          },
-        ],
-      },
-    ],
-  },
+    {
+      value: 'zh-cn',
+      label: '简体',
+    },
+    {
+    value: 'zh-cn',
+    label: '简体',
+    },
+    {
+      value: 'zh-cn',
+      label: '简体',
+    },
   ])
 const optionsT = ref([
   {

+ 54 - 1
TEAMModelOS.SDK/Models/Cosmos/Common/Activity.cs

@@ -89,6 +89,55 @@ namespace TEAMModelOS.SDK.Models
         public int publish { get; set; }
     }
 
+
+    public class ActivityWebsite : CosmosEntity {
+        // id(区级id,校级id)
+        //code:ActivityWebsite
+        public ActivityWebsite() {
+            code="ActivityWebsite";
+            pk="ActivityWebsite";
+        }
+        /// <summary>
+        /// (路由编码),公开的 teammodel ,区级(standard字段),校级(学校编码),可以修改
+        /// </summary>
+        [Required(ErrorMessage = "不能为空")]
+        public string route { get; set; }
+        /// <summary>
+        /// "public公开/area区级/school校级",  public公开活动 只能是醍摩豆智慧学区才能选择,
+        /// </summary>
+        [Required(ErrorMessage = "Required")]
+        public string scope { get; set; }
+        [Required(ErrorMessage = "name不能为空")]
+        public string name { get; set; } = "教师专业化发展服务平台";
+        public string logo { get; set; }
+        public List<ActivityBanner> banners { get; set; } = new List<ActivityBanner>();
+
+    }
+    public class ActivityBanner { 
+        public string title { get; set; }
+        public string subtitle { get; set; }
+        /// <summary>
+        /// 指向链接
+        /// </summary>
+        public string url { get; set; }
+       /// <summary>
+       /// 图片链接
+       /// </summary>
+        public string blob { get; set; }
+        /// <summary>
+        /// 文件类型  video  image
+        /// </summary>
+        public string fileType { get; set; }
+        /// <summary>
+        /// 添加时间
+        /// </summary>
+        public long time { get; set; }
+        /// <summary>
+        /// 展示到期时间,-1永不过期
+        /// </summary>
+        public long expire { get; set; }
+    }
+
     public class ActivityTeacher
     {
         public string id { get; set; }
@@ -232,9 +281,13 @@ namespace TEAMModelOS.SDK.Models
         public long stime { get; set; }
         public long etime { get; set; }
         /// <summary>
+        /// file  sokrates
+        /// </summary>
+        public string type { get; set; }
+        /// <summary>
         /// ["file"], 提交作品的格式
         /// </summary>
-        public List<string> type { get; set; }
+        public List<string> fileType { get; set; } = new List<string>();
         public string desc { get; set;}
     }
     public class ContestSign

+ 1 - 1
TEAMModelOS.SDK/Models/Cosmos/Normal/TMDOrder.cs

@@ -67,7 +67,7 @@ namespace TEAMModelOS.SDK.Models
         /// <summary>
         /// 发票代码
         /// </summary>
-        public string invoiceCode { get; set; }
+        public string? invoiceCode { get; set; }
         /// <summary>
         /// 发票号码
         /// </summary>

+ 1 - 1
TEAMModelOS.SDK/Models/Service/Common/TeacherService.cs

@@ -113,7 +113,7 @@ namespace TEAMModelOS.Services
                         //{
                         //    setting.accessConfig = null;
                         //}
-                        areas.Add(new AreaDto { areaId = area?.id, name = area?.name, standard = area?.standard, standardName = area?.standardName, setting = setting, access = access });
+                        areas.Add(new AreaDto { areaId = area?.id, name = area?.name, standard = area?.standard, standardName = area?.standardName, setting = setting, access = access ,shortCode=area.shortCode});
                     }
                 }
                 //处理导入时,在学校名单有该教师加入的,但是基本信息没有的 

+ 1 - 0
TEAMModelOS/ClientApp/public/lang/en-US.js

@@ -1577,6 +1577,7 @@ const LANG_EN_US = {
         choosePageItems: 'Select all questions in this page',
         completeTip: 'Please complete the subject, grade and semester data for the current school system first!',
         canChoose: 'choice(s)',
+        xkw: 'zxxk.com',
         xkwMode: 'Academic Web Design',
         importItems: 'Import Question',
         composePaper: 'Form Exam File',

+ 1 - 0
TEAMModelOS/ClientApp/public/lang/zh-CN.js

@@ -1576,6 +1576,7 @@ const LANG_ZH_CN = {
         choosePageItems: '选择本页所有题目',
         completeTip: '请先完善当前学段的科目、年级及学期数据!',
         canChoose: '道题可选',
+        xkw: '学科网',
         xkwMode: '学科网组卷',
         importItems: '试题导入',
         composePaper: '组成试卷',

+ 1 - 0
TEAMModelOS/ClientApp/public/lang/zh-TW.js

@@ -1579,6 +1579,7 @@ const LANG_ZH_TW = {
         choosePageItems: '選擇本頁所有題目',
         completeTip: '請先完善當前學段的科目、年級及學期數據!',
         canChoose: '道題可選',
+        xkw: '學科網',
         xkwMode: '學科網組卷',
         importItems: '試題匯入',
         composePaper: '組成試卷',

+ 10 - 10
TEAMModelOS/ClientApp/src/view/areaMgmt/AreaLayout.vue

@@ -203,16 +203,16 @@ export default {
     },
     //教师个人跳转苏格拉底
     toPrivSokrate () {
-      // this.getLoginCode().then(
-      //   res => {
-      //     this.loginCode = res.code
-      //     let url = `${this.curSiteConfig.sokrateUrl}/auth/login/callback-habook?code=${this.loginCode}`
-      //     window.open(url, '', 'noopener')
-      //   }
-      // ).finally(() => {
-      //   this.isLoading = false
-      // })
-      window.open('https://sokrates.teammodel.cn/district/CDHT#/')
+      this.getLoginCode().then(
+        res => {
+          this.loginCode = res.code
+          let areaCode = this.curArea.shortCode
+          let url = areaCode ? `https://sokrates.teammodel.cn/auth/login/login-to-district?district_shortcode=${areaCode}&code=${res.code}` : `${this.curSiteConfig.sokrateUrl}/auth/login/callback-habook?code=${this.loginCode}`
+          window.open(url, '', 'noopener')
+        }
+      ).finally(() => {
+        this.isLoading = false
+      })
     },
     toActivity () {
       this.getLoginCode().then(

+ 160 - 123
TEAMModelOS/ClientApp/src/view/coursemgt/components/ImportTask.vue

@@ -10,7 +10,7 @@
 			</Upload>
 			<div class="tip-wrap">
 				<div class="download-wrap">
-					<span style="color: #41cdec;cursor: pointer;" @click="onDownloadFiles">{{ $t('newCusMgt.downloadFiles') }}</span>
+					<span style="color: #41cdec; cursor: pointer" @click="onDownloadFiles">{{ $t("newCusMgt.downloadFiles") }}</span>
 					<Dropdown @on-click="onDownloadTemp">
 						<a href="javascript:void(0)" style="font-size: 14px; margin-left: 20px; color: #41cdec">
 							{{ $t("evaluation.importFile.templateDownload") }}
@@ -37,29 +37,31 @@
 				<template slot-scope="{ row, index }" slot="grade">
 					<span>{{ curPeriod.grades[row.grade] }}</span>
 				</template>
-				<!-- <template slot-scope="{ row, index }" slot="assistants">
-					<span>{{ row.assistants ? getTchName(row.assistants[0]) : "-" }}</span>
-				</template> -->
-                <template slot-scope="{ row, index }" slot="invalidCode">
-					<span :style="{ color: row.invalidCode === 0 ? '#19be6d' : '#ff0000' }">{{ errorArr.find(i => i.code === row.invalidCode).msg }}</span>
+				<template slot-scope="{ row, index }" slot="assistants">
+					<span>{{ row.assistants ? row.assistants.split(',').length + $t('teachermgmt.peopleUnit') : "-" }}</span>
+				</template>
+				<template slot-scope="{ row, index }" slot="invalidCode">
+					<span :style="{ color: row.invalidCode === 0 ? '#19be6d' : '#ff0000' }">{{ errorArr.find((i) => i.code === row.invalidCode).msg }}</span>
 				</template>
 			</Table>
-			<p style="margin: 20px 0;color:red;">* {{ $t('newCusMgt.tip4') }}<span style="color:#19be6b">{{ $t('newCusMgt.tip5') }}</span></p>
-            <div class="btn-wrap">
-                <Button @click="reImport"> {{$t('cusMgt.cusImp11')}}</Button>
-                <Button type="success" :loading="btnLoading" @click="confirmImport" :disabled="!canImportList.length"> {{$t('cusMgt.cusImp10')}}</Button>
-            </div>
+			<p style="margin: 20px 0; color: red">
+				* {{ $t("newCusMgt.tip4") }}<span style="color: #19be6b">{{ $t("newCusMgt.tip5") }}</span>
+			</p>
+			<div class="btn-wrap">
+				<Button @click="reImport"> {{ $t("cusMgt.cusImp11") }}</Button>
+				<Button type="success" :loading="btnLoading" @click="confirmImport" :disabled="!canImportList.length"> {{ $t("cusMgt.cusImp10") }}</Button>
+			</div>
 		</div>
 	</div>
-</template> 
+</template>
 
 <script>
 	import excel from "@/utils/excel.js";
 	export default {
 		data() {
 			return {
-                canImportList:[],
-                checkToken:null,
+				canImportList: [],
+				checkToken: null,
 				btnLoading: false,
 				isPreview: false,
 				isImporting: false,
@@ -67,22 +69,22 @@
 				columns: [
 					{
 						key: "name",
-						title: this.$t('cusMgt.cusName'),
+						title: this.$t("cusMgt.cusName"),
 						align: "center"
 					},
 					{
 						key: "courseNo",
-						title: this.$t('newCusMgt.no'),
+						title: this.$t("newCusMgt.no"),
 						align: "center"
 					},
 					{
 						slot: "grade",
-						title: this.$t('newCusMgt.grade'),
+						title: this.$t("newCusMgt.grade"),
 						align: "center"
 					},
 					{
 						key: "list",
-						title: this.$t('newCusMgt.list'),
+						title: this.$t("newCusMgt.list"),
 						align: "center",
 						width: 140
 					},
@@ -94,18 +96,18 @@
 					// },
 					{
 						slot: "tmdid",
-						title: this.$t('newCusMgt.tmdid'),
+						title: this.$t("newCusMgt.tmdid"),
 						align: "center",
 						width: 100
 					},
 					{
 						slot: "assistants",
-						title: this.$t('newCusMgt.assistantsId'),
+						title: this.$t("newCusMgt.assistantsId"),
 						align: "center"
 					},
 					{
 						slot: "invalidCode",
-						title: this.$t('newCusMgt.invalidCode'),
+						title: this.$t("newCusMgt.invalidCode"),
 						align: "center",
 						width: 100
 					}
@@ -138,29 +140,62 @@
 				};
 				reader.readAsBinaryString(file);
 			},
+			mergeObjects(array) {
+				let mergedArray = [];
+
+				// 遍历数组中的每个对象
+				for (let i = 0; i < array.length; i++) {
+					let currentObject = array[i];
+					let isDuplicate = false;
+
+					// 检查是否有与当前对象相同的对象存在
+					for (let j = 0; j < mergedArray.length; j++) {
+						let mergedObject = mergedArray[j];
+						if (currentObject.courseNo === mergedObject.courseNo && currentObject.list === mergedObject.list && currentObject.tmdid === mergedObject.tmdid) {
+							// 如果找到相同的对象,则将当前对象的d字段合并到已存在的对象的d字段中
+							mergedObject.assistants = mergedObject.assistants + ',' + currentObject.assistants;
+							isDuplicate = true;
+							break;
+						}
+					}
+
+					// 如果未找到相同的对象,则将当前对象添加到合并后的数组中
+					if (!isDuplicate) {
+						mergedArray.push(currentObject);
+					} else {
+						// 如果找到相同的对象,将当前对象从原始数组中删除,避免后续循环中再次遇到它
+						array.splice(i, 1);
+						i--; // 调整索引以继续检查下一个对象
+					}
+				}
+
+				return mergedArray;
+			},
 			/* 导入操作 */
 			onBeforeImportUpload(file) {
 				let maxSize = 10 * 1024 * 1024;
 				let nameType = file.name.split(".")[file.name.split(".").length - 1];
 				if (!["xls", "xlsx"].includes(nameType.toLowerCase())) {
-					this.$Message.warning(this.$t('newCusMgt.tip6'));
+					this.$Message.warning(this.$t("newCusMgt.tip6"));
 					return false;
 				}
 				if (file.size > maxSize) {
-					this.$Message.warning(this.$t('newCusMgt.tip7'));
+					this.$Message.warning(this.$t("newCusMgt.tip7"));
 					return false;
 				}
 				this.isImporting = true;
 				this.readExcel(file, (data) => {
 					this.importPercent = 20;
 					console.log(data.results);
-					data.results.forEach(i => {
-						i.grade = i.grade - 1
-						i.tmdid = i.tmdid + ''
-						i.courseNo = i.courseNo + ''
-						i.assistants = isNaN(i.assistants) ? i.assistants : i.assistants + ''
-					})
-					let { year,id } = this.$store.state.user.curSemester
+					data.results.forEach((i) => {
+						i.grade = i.grade - 1;
+						i.tmdid = i.tmdid + "";
+						i.courseNo = i.courseNo + "";
+						i.assistants = isNaN(i.assistants) ? i.assistants : i.assistants + "";
+					});
+					// data.results = this.mergeObjects(data.results)
+
+					let { year, id } = this.$store.state.user.curSemester;
 					this.$api.newCourse
 						.courseManage({
 							scope: "school",
@@ -168,12 +203,12 @@
 							periodId: this.$store.state.user.curPeriod.id,
 							semesterId: id,
 							studyYear: year,
-							courseCheckImports: data.results
+							courseCheckImports: this.mergeObjects(data.results)
 						})
 						.then((res) => {
-                            this.checkToken = res.checkToken
-                            this.importResult = res.courseInvalidImports.concat(res.courseVerifiedImports)
-                            this.canImportList = res.courseVerifiedImports
+							this.checkToken = res.checkToken;
+							this.importResult = res.courseInvalidImports.concat(res.courseVerifiedImports);
+							this.canImportList = res.courseVerifiedImports;
 							this.isPreview = true;
 							this.isImporting = false;
 							this.importPercent = 100;
@@ -182,7 +217,7 @@
 					return;
 				});
 			},
-            /* 确认导入 */
+			/* 确认导入 */
 			confirmImport() {
 				this.btnLoading = true;
 				this.$api.newCourse
@@ -225,82 +260,84 @@
 				downloadRes();
 			},
 			/* 导出备用资料 */
-			onDownloadFiles(){
-				let parentPage = this.$parent.$parent
+			onDownloadFiles() {
+				let parentPage = this.$parent.$parent;
 				console.log(parentPage.allClassList);
 				console.log(parentPage.teacherList);
 				console.log(parentPage.originCourseList);
-				let curSemesterYear = this.$store.state.user.curSemester.year
-				let sheets = []
+				let curSemesterYear = this.$store.state.user.curSemester.year;
+				let sheets = [];
 				// 班级名单
-				let class_Headers = [`${this.$t('cusMgt.listName')}(name)`, `${this.$t('cusMgt.nameListType')}(type)`, `${this.$t('newCusMgt.no')}(list)`,`${this.$t('newCusMgt.year')}(year)`,  `${this.$t('cusMgt.stuCount')}`]
-				let class_Keys = ['name', 'type', 'no', 'year',  'scount']
-				let class_datas = []
-				parentPage.allClassList.filter(i => i.type !== 'research' && i.type !== 'yxtrain').forEach(classItem => {
-					class_datas.push({
-						name:classItem.name,
-						year:classItem.year,
-						no:classItem.year + '-' + classItem.no,
-						type:classItem.type,
-						scount:classItem.scount,
-					})
-				})
+				let class_Headers = [`${this.$t("cusMgt.listName")}(name)`, `${this.$t("cusMgt.nameListType")}(type)`, `${this.$t("newCusMgt.no")}(list)`, `${this.$t("newCusMgt.year")}(year)`, `${this.$t("cusMgt.stuCount")}`];
+				let class_Keys = ["name", "type", "no", "year", "scount"];
+				let class_datas = [];
+				parentPage.allClassList
+					.filter((i) => i.type !== "research" && i.type !== "yxtrain")
+					.forEach((classItem) => {
+						class_datas.push({
+							name: classItem.name,
+							year: classItem.year,
+							no: classItem.year + "-" + classItem.no,
+							type: classItem.type,
+							scount: classItem.scount
+						});
+					});
 				const classSheet = {
 					title: class_Headers,
 					key: class_Keys,
 					data: class_datas,
-					filename: this.$t('cusMgt.classList'),
+					filename: this.$t("cusMgt.classList"),
 					autoWidth: true
-				}
-				sheets.push(classSheet)
+				};
+				sheets.push(classSheet);
 				// 教师名单
-				let teacher_Headers = [this.$t('cusMgt.teaName') + '(tmdName)', this.$t('teachermgmt.table.th1') + '(tmdid)', this.$t('teachermgmt.tcUpd8'), this.$t('cusMgt.job'), this.$t('user.mobile'), this.$t('teachermgmt.page.text3'),this.$t('teachermgmt.tcUpd5')]
-				let teacher_Keys = ['name', 'id', 'iname', 'job', 'phone', 'group', 'subject']
-				let teacher_datas = []
-				parentPage.teacherList.forEach(teacher => {
+				let teacher_Headers = [this.$t("cusMgt.teaName") + "(tmdName)", this.$t("teachermgmt.table.th1") + "(tmdid)", this.$t("teachermgmt.tcUpd8"), this.$t("cusMgt.job"), this.$t("user.mobile"), this.$t("teachermgmt.page.text3"), this.$t("teachermgmt.tcUpd5")];
+				let teacher_Keys = ["name", "id", "iname", "job", "phone", "group", "subject"];
+				let teacher_datas = [];
+				parentPage.teacherList.forEach((teacher) => {
 					teacher_datas.push({
-						name:teacher.name,
+						name: teacher.name,
 						id: teacher.id,
-						iname:teacher.iname || '-',
-						job:teacher.job || '-',
-						phone:teacher.phone || '-',
-						group:teacher.groups.map(i => i.name).join(','),
-						subject:teacher.subjectIds.map(i => parentPage.curPeriod.subjects.find(k => k.id === i)?.name || '-').join(','),
-					})
-				})
+						iname: teacher.iname || "-",
+						job: teacher.job || "-",
+						phone: teacher.phone || "-",
+						group: teacher.groups.map((i) => i.name).join(","),
+						subject: teacher.subjectIds.map((i) => parentPage.curPeriod.subjects.find((k) => k.id === i)?.name || "-").join(",")
+					});
+				});
 				const teacherSheet = {
 					title: teacher_Headers,
 					key: teacher_Keys,
 					data: teacher_datas,
-					filename: this.$t('teachermgmt.teacherList'),
+					filename: this.$t("teachermgmt.teacherList"),
 					autoWidth: true
-				}
-				sheets.push(teacherSheet)
+				};
+				sheets.push(teacherSheet);
 				// 课程名单
-				let course_Headers = [`${this.$t('cusMgt.listName')}(name)`, `${this.$t('newCusMgt.no')}(courseNo)`, `${this.$t('newCusMgt.grade')}(grade)`, `${this.$t('newCusMgt.subject')}(subject)`, `${this.$t('newCusMgt.desc')}(desc)`, this.$t('jyzx.offline.creator')]
-				let course_Keys = ['name', 'no', 'grade', 'subject', 'desc', 'creator']
-				let course_datas = []
-				parentPage.originCourseList.forEach(course => {
+				let course_Headers = [`${this.$t("cusMgt.listName")}(name)`, `${this.$t("newCusMgt.no")}(courseNo)`, `${this.$t("newCusMgt.grade")}(grade)`, `${this.$t("newCusMgt.subject")}(subject)`, `${this.$t("newCusMgt.desc")}(desc)`, this.$t("jyzx.offline.creator")];
+				let course_Keys = ["name", "no", "grade", "subject", "desc", "creator"];
+				let course_datas = [];
+				parentPage.originCourseList.forEach((course) => {
 					course_datas.push({
-						name:course.name,
-						no: course.no || '-',
+						name: course.name,
+						no: course.no || "-",
 						grade: course.grade + 1,
-						subject:course.subject.name,
-						desc:course.desc || '-',
-						creator:course.creatorName + '(' + course.creatorId +')',
-					})
-				})
+						subject: course.subject.name,
+						desc: course.desc || "-",
+						creator: course.creatorName + "(" + course.creatorId + ")"
+					});
+				});
 				const courseSheet = {
 					title: course_Headers,
 					key: course_Keys,
 					data: course_datas,
-					filename: this.$t('courseManage.courseList'),
+					filename: this.$t("courseManage.courseList"),
 					autoWidth: true
-				}
-				sheets.push(courseSheet)
+				};
+				sheets.push(courseSheet);
 				let schoolName = this.$store.state.user.schoolProfile.school_base.name;
 				let periodName = parentPage.curPeriod.name;
-				excel.export_array_to_sheet(sheets, `${schoolName}-${periodName} ${this.$t('newCusMgt.recommendFiles')}`)
+				excel.export_array_to_sheet(sheets, `${schoolName}-${periodName} ${this.$t("newCusMgt.recommendFiles")}`);
 			}
 		},
 		computed: {
@@ -311,52 +348,52 @@
 			curYear() {
 				return new Date().getFullYear();
 			},
-            /* 获取教师姓名 */
+			/* 获取教师姓名 */
 			getTchName() {
 				return (tchId) => {
 					return this.$parent.$parent.teacherList.find((i) => i.id === tchId)?.name;
 				};
 			},
-            errorArr(){
-                return [
-                    {
-                        code:0,
-                        msg:this.$t('newCusMgt.normal')
-                    },
-                    {
-                        code:1,
-                        msg:this.$t('newCusMgt.errorTip1')
-                    },
-                    {
-                        code:2,
-                        msg:this.$t('newCusMgt.errorTip2')
-                    },
-                    {
-                        code:3,
-                        msg:this.$t('newCusMgt.errorTip3')
-                    },
-                    {
-                        code:4,
-                        msg:this.$t('newCusMgt.errorTip4')
-                    },
-                    {
-                        code:5,
-                        msg:this.$t('newCusMgt.errorTip5')
-                    },
+			errorArr() {
+				return [
 					{
-                        code:12,
-                        msg:this.$t('newCusMgt.errorTip7')
-                    },
-                    {
-                        code:21,
-                        msg:this.$t('newCusMgt.errorTip6')
-                    },
+						code: 0,
+						msg: this.$t("newCusMgt.normal")
+					},
+					{
+						code: 1,
+						msg: this.$t("newCusMgt.errorTip1")
+					},
 					{
-                        code:22,
-                        msg:this.$t('newCusMgt.tip3')
-                    },
-                ]
-            }
+						code: 2,
+						msg: this.$t("newCusMgt.errorTip2")
+					},
+					{
+						code: 3,
+						msg: this.$t("newCusMgt.errorTip3")
+					},
+					{
+						code: 4,
+						msg: this.$t("newCusMgt.errorTip4")
+					},
+					{
+						code: 5,
+						msg: this.$t("newCusMgt.errorTip5")
+					},
+					{
+						code: 12,
+						msg: this.$t("newCusMgt.errorTip7")
+					},
+					{
+						code: 21,
+						msg: this.$t("newCusMgt.errorTip6")
+					},
+					{
+						code: 22,
+						msg: this.$t("newCusMgt.tip3")
+					}
+				];
+			}
 		}
 	};
 </script>

+ 5 - 2
TEAMModelOS/ClientApp/src/view/evaluation/bank/index.vue

@@ -60,7 +60,7 @@
                    
                 </span>
               </DropdownItem>
-              <DropdownItem name="go_share">
+              <DropdownItem name="go_share" v-if="hasSchool">
                 <span @click="goShare" class="bank-tools-btn" v-show="$access.can('admin.*||exercise-upd')">
                    
                   <Icon type="ios-redo" size="16" />
@@ -72,7 +72,7 @@
                 <span @click="doXkwAuth" class="bank-tools-btn" v-show="hasXkwAuth && !inGlobalSite">
                    
                   <Icon type="ios-send" size="16" />
-                  <span>学科网</span>
+                  <span>{{ $t('evaluation.xkw')}}</span>
                    
                 </span>
               </DropdownItem>
@@ -305,6 +305,9 @@ export default {
     isSchool() {
       return this.$route.name === "schoolBank";
     },
+    hasSchool(){
+      return this.$store.state.userInfo.hasSchool
+    },
     paperScrollTop() {
       return this.$store.state.totalAnalysis.paperScrollTop
     },

+ 4 - 1
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseMultiple.vue

@@ -297,7 +297,10 @@
 			this.$editorTools.initMyEditor(stemEditor,this)
 			stemEditor.create()
 			this.stemEditor = stemEditor
-			this.initEditors()
+
+			if(JSON.stringify(this.editInfo) === '{}'){
+				this.initEditors()
+			}
 
 			if (this.editInfo && this.isEdit) { 
 				console.log('进入多选题Mounted编辑')

+ 4 - 1
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseSingle.vue

@@ -248,7 +248,10 @@
 
 			stemEditor.create()
 			this.stemEditor = stemEditor
-			this.initEditors()
+
+			if(JSON.stringify(this.editInfo) === '{}'){
+				this.initEditors()
+			}
 
 			if (this.editInfo && this.isEdit) {
 				console.log('进入单选题Mounted编辑',this.editInfo)

+ 8 - 4
TEAMModelOS/ClientApp/src/view/iot/areaiot.vue

@@ -75,7 +75,7 @@
                                         <span class="timetag">Min</span>
                                         <br/>
                                         <span>
-                                            <span class="total-text">总计</span>
+                                            <span class="total-text">{{$t('schoolIot.basics.totals')}}</span>
                                             {{Math.round(item.value/60)}}
                                             <span class="timetag">H</span>
                                         </span>
@@ -369,10 +369,14 @@ export default {
        this.$api.iot.getAreaiot(data).then((res) => {
         console.log(res,'area iot back')
           //header基础数据
-          let { classCnt, deviceAuthCnt,tmidCnt,teacherCnt, stuShow, studentCnt, stuLessonLengMin, lessonRecord, lessonLengMin } = res.area
-          this.basicaList[0].value = classCnt
+          let { classCnt, deviceAuthCnt,tmidCnt,teacherCnt, stuShow, studentCnt, stuLessonLengMin, lessonRecord, lessonLengMin,} = res.area
+          let {iotData}=res.iotData
+          let areaDataclass=[];let areaDatateach=[];
+          let useClass=iotData.length >0 ? iotData.forEach((item)=>{item.deviceList.length >0 ?areaDataclass.concat(item.deviceList):''}):0
+          let useTeach=iotData.length >0 ? iotData.forEach((item)=>{item.tmidList.length >0 ? areaDatateach.concat(item.tmidList):''}):0
+          this.basicaList[0].value = [...new Set(areaDataclass)].length
           this.basicaList[0].total = deviceAuthCnt
-          this.basicaList[1].value= tmidCnt
+          this.basicaList[1].value= [...new Set(areaDatateach)].length
           this.basicaList[1].total = teacherCnt
           this.basicaList[2].value = stuShow
           this.basicaList[2].total = studentCnt

+ 8 - 3
TEAMModelOS/ClientApp/src/view/iot/schooliot.vue

@@ -312,10 +312,15 @@ export default {
         this.$api.iot.getSchooliot(data).then((res)=>{
           console.log(res, 'iot back')
           //header基础数据
-          let { classCnt, deviceAuthCnt, teacherShow,teacherCnt, stuShow, studentCnt, stuLessonLengMin, lessonRecord, lessonLengMin } = res
-          this.basicaList[0].value = classCnt
+          let { classCnt, deviceAuthCnt, teacherShow,teacherCnt, stuShow, studentCnt, stuLessonLengMin, lessonRecord, lessonLengMin,iotData } = res
+          let useDataclass=[];let uesDatateach=[];
+          let useClass=iotData.length >0 ? iotData.forEach((item)=>{item.deviceList.length >0 ?useDataclass.concat(item.deviceList):''})
+          :0
+          let useTeach=iotData.length >0 ? iotData.forEach((item)=>{item.tmidList.length >0 ? uesDatateach.concat(item.tmidList):''})
+          :0
+          this.basicaList[0].value = [...new Set(useDataclass)].length
           this.basicaList[0].total = deviceAuthCnt
-          this.basicaList[1].value= teacherShow
+          this.basicaList[1].value= [...new Set(uesDatateach)].length
           this.basicaList[1].total = teacherCnt
           this.basicaList[2].value = stuShow
           this.basicaList[2].total = studentCnt

+ 2 - 2
TEAMModelOS/ClientApp/src/view/login/page/Student.vue

@@ -183,12 +183,12 @@
             <p class="other-login-text">{{$t('login.communy.wechat')}}</p>
           </div>
           <!-- 教育雲 -->
-          <div class="other-login-item" @click="oauthLogin('educloudtw')" v-if="srvAdr == 'Global'">
+          <!-- <div class="other-login-item" @click="oauthLogin('educloudtw')" v-if="srvAdr == 'Global'">
             <v-icon iconClass="educloudtw" class="icon-educlowudtw"></v-icon>
             <p class="other-login-text">
               {{$t('教育雲')}}
             </p>
-          </div>
+          </div> -->
         </div>
       </div>
       <!-- 醍摩豆qrcode登录 -->

+ 18 - 1
TEAMModelOS/Controllers/Common/ActivityController.cs

@@ -54,6 +54,20 @@ namespace TEAMModelOS.Controllers
             _coreAPIHttpService = coreAPIHttpService;
         }
 
+        /// <summary>
+        /// 路由管理
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [AuthToken(Roles = "admin,area")]
+        [HttpPost("website-manage")]
+        [Authorize(Roles = "IES")]
+
+        public async Task<IActionResult> RouteManage(JsonElement request) {
+
+            return Ok();
+        }
 
         /// <summary>
         /// 添加活动参与对象,学校,教师
@@ -426,10 +440,13 @@ namespace TEAMModelOS.Controllers
                                     }
                                 });
                             }
-                            break;
+                            return Ok(new { activities = activities.OrderByDescending(z => z.stime) });
                         }
                     case bool when $"{grant_type}".Equals("list-portal", StringComparison.OrdinalIgnoreCase):
                         {
+                            if (!request.TryGetProperty("route", out JsonElement _route)) return BadRequest();
+                         
+
                             break;
                         }
                 }

+ 5 - 5
TEAMModelOS/Controllers/System/WeChatPayController.cs

@@ -524,7 +524,7 @@ namespace TEAMModelOS.Controllers
         [EnableCors("AllowSpecificOrigin")]
         [HttpPost("upload-invoice")]
         [RequestSizeLimit(102_400_000_00)]//最大10000m左右
-        public async Task<IActionResult> UploadInvoice([FromForm] IFormFile invoiceFile, [FromForm] string order_no, [FromForm] string invoiceCode, [FromForm] string invoiceNum)
+        public async Task<IActionResult> UploadInvoice([FromForm] IFormFile invoiceFile, [FromForm] string order_no, /*[FromForm] string invoiceCode,*/ [FromForm] string invoiceNum)
         {
             string fileExt = FileType.GetExtention(invoiceFile.FileName).ToLower();
             if (fileExt.Equals("pdf", StringComparison.OrdinalIgnoreCase))
@@ -536,7 +536,7 @@ namespace TEAMModelOS.Controllers
                     var container = _azureStorage.GetBlobContainerClient(order.buyer_tmid);
                     await container.CreateIfNotExistsAsync(PublicAccessType.None); 
                     var url = await _azureStorage.GetBlobContainerClient(order.buyer_tmid).UploadFileByContainer(invoiceFile.OpenReadStream(), "invoice", $"{order.id}_{order.transaction_id}.{fileExt}");
-                    order.invoiceCode = invoiceCode;
+                    //order.invoiceCode = invoiceCode;
                     order.invoiceNum = invoiceNum;
                     order.invoiceUrl = url;
                     if (!string.IsNullOrWhiteSpace(order.buyer_email) &&order. invoiceNotify!=3)
@@ -556,14 +556,14 @@ namespace TEAMModelOS.Controllers
                                 html= html.Replace("{tmdname}", order.buyer_name).Replace("{productName}", order.item_desc)
                                     .Replace("{orderId}", order.order_no).Replace("{pay_amount}", $"{order.pay_amount*1.0/100}")
                                     .Replace("{invoiceCode}", order.invoiceCode).Replace("{invoiceNum}", order.invoiceNum)
-                                    .Replace("{invoiceUrl}",$"{order.invoiceUrl}?{sas.sas}").Replace("{year}",$"{DateTimeOffset.Now.Year}")
+                                    .Replace("{invoiceUrl}",$"{order.invoiceUrl}").Replace("{year}",$"{DateTimeOffset.Now.Year}")
                                     .Replace("{pay_time}", DateTimeOffset.FromUnixTimeMilliseconds(order.qrcode_time).ToString("yyyy-MM-dd HH:mm:ss"));
                                 string buyer_email = order.buyer_email;
                                 if (_option.Location.Contains("Test", StringComparison.OrdinalIgnoreCase) || _option.Location.Contains("Dep", StringComparison.OrdinalIgnoreCase)) {
-                                   // order.buyer_email="353897079@qq.com";
+                                order.buyer_email="353897079@qq.com";
                                 }
                                 var token = _mailFactory.GetSmtpClient().SendEmail(_azureCosmosFactory, _dingDing, order, "发票开具通知", html, buyer_email, order.buyer_tmid, order.buyer_name);
- 
+                                //var tokenAdmin = _mailFactory.GetSmtpClient().SendEmail(_azureCosmosFactory, _dingDing, order, "发票开具通知(管理员)", html, "353897079@qq.com", "15283771540", "醍摩豆研发管理员");
                                 //通知订单系统 
                                 {
                                     try

+ 84 - 7
TEAMModelOS/Controllers/Third/Sc/ScDataPushController.cs

@@ -27,6 +27,9 @@ using System;
 using System.Web;
 using System.Security.Policy;
 using TEAMModelOS.Controllers.Third.LePei;
+using DocumentFormat.OpenXml.Wordprocessing;
+using System.Text.RegularExpressions;
+using Microsoft.Azure.Cosmos.Linq;
 
 namespace TEAMModelOS.Controllers
 {
@@ -163,7 +166,8 @@ namespace TEAMModelOS.Controllers
         private readonly IConverter _converter;
         public readonly string type = "scsyxpt";
         public readonly IHttpClientFactory _httpClient;
- 
+        public static readonly string invalidChars = @"[\\/:*?""<>|]"; // 使用正则表达式替换特殊符号为空字符串
+
         public IConfiguration _configuration { get; set; }
 
         public ScDataPushController(IHttpClientFactory httpClient,IConverter converter,  AzureCosmosFactory azureCosmos,   AzureStorageFactory azureStorage,  IConfiguration configuration)
@@ -444,7 +448,7 @@ namespace TEAMModelOS.Controllers
             List<string> pushTeachers = new List<string> { userid};
             School schoolData =await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new PartitionKey("Base"));
             (List<ScsResult> results, List<PushFail> fails, List<Dictionary<string, object>> dicts) = await PushData(schoolData.areaId, schools, pushTeachers);
-            (List<dynamic> ycd, List<dynamic> okd, List<TeacherSc> teachers, List<PushData> datas) = await CheckScPush(pushTeachers, schoolData.areaId, schools, ProjectItemID);
+            (List<dynamic> ycd, List<dynamic> okd, List<TeacherSc> teachers, List<PushData> datas,List<dynamic> files) = await CheckScPush(pushTeachers, schoolData.areaId, schools, ProjectItemID);
             return Ok(new { results, fails, dicts, ycd, okd, teachers, datas });
         }
 
@@ -1137,7 +1141,7 @@ namespace TEAMModelOS.Controllers
             string areaIdJson = $"{json.GetProperty("areaId")}";
             List<string> schools = json.GetProperty("schools").ToObject<List<string>>();
             var client = _azureCosmos.GetCosmosClient();
-            (List<dynamic> ycd, List<dynamic> okd, List<TeacherSc> teachers,List<PushData> datas)= await CheckScPush(pushTeachers, areaIdJson, schools, ProjectItemID);
+            (List<dynamic> ycd, List<dynamic> okd, List<TeacherSc> teachers,List<PushData> datas, List<dynamic> files)= await CheckScPush(pushTeachers, areaIdJson, schools, ProjectItemID);
             List<string> pxids = json.GetProperty("pxids").ToObject<List<string>>();
             List<PushData> ycData = new List<PushData>();
             List<dynamic> ycds = new List<dynamic>();
@@ -1166,6 +1170,8 @@ namespace TEAMModelOS.Controllers
                     int hgCount = groupData.ToList().Where(x => x.teacherInfo.ComPassed == 1).Count();
                     var yc = groupData.ToList().Where(x => x.teacherInfo.ComPassed != 2 && x.teacherInfo.ComPassed != 1);
                     int ycCount = yc.Count();
+
+                    files.Add(new { schoolName = groupData.Key, joinCount, yxCount, hgCount, ycCount, files = groupData.ToList().Select(z => z.files) });
                     okd.Add(new { schoolName = groupData.Key, joinCount, yxCount, hgCount, ycCount });
                     if (yc.Any())
                     {
@@ -1215,9 +1221,9 @@ namespace TEAMModelOS.Controllers
                     });
                 });
             }
-            return Ok(new { ycData = ycd, okData = okd , tmdid= teachers .Select(x=>x.tmdid), datas = datas, ycds });
+            return Ok(new { ycData = ycd, okData = okd , tmdid= teachers .Select(x=>x.tmdid), datas = datas, ycds , files });
         }
-        private async Task<(List<dynamic> ycd ,List<dynamic> okd, List<TeacherSc> teachers, List<PushData> datas)> CheckScPush(List<string> pushTeachers,string areaIdJson,List<string> schools,string ProjectItemID) {
+        private async Task<(List<dynamic> ycd ,List<dynamic> okd, List<TeacherSc> teachers, List<PushData> datas, List<dynamic> files)> CheckScPush(List<string> pushTeachers,string areaIdJson,List<string> schools,string ProjectItemID) {
 
             Dictionary<string, Dictionary<string, object>> pushDatas = new Dictionary<string, Dictionary<string, object>>();
             List<Dictionary<string, object>> dicts = new List<Dictionary<string, object>>();
@@ -1304,6 +1310,7 @@ namespace TEAMModelOS.Controllers
             List<KeyValuePair<string, string>> htmls = new List<KeyValuePair<string, string>>();
             var group = datas.GroupBy(x => x.teacherInfo.SchoolName);
             List<dynamic> okd = new List<dynamic>();
+            List<dynamic>files = new List<dynamic>();
             foreach (var groupData in group)
             {
                 int joinCount = groupData.ToList().Count();
@@ -1313,6 +1320,8 @@ namespace TEAMModelOS.Controllers
                 var yc = groupData.ToList().Where(x => x.teacherInfo.ComPassed != 2 && x.teacherInfo.ComPassed != 1);
                 int ycCount = yc.Count();
                 okd.Add(new { schoolName = groupData.Key, joinCount, yxCount, hgCount, ycCount });
+
+                files.Add(new { schoolName = groupData.Key, joinCount, yxCount, hgCount, ycCount , files= groupData .ToList().Select(z=>z.files)});
                 if (yc.Any())
                 {
                     foreach (var bu in yc)
@@ -1362,13 +1371,81 @@ namespace TEAMModelOS.Controllers
             });
             if (datas.Any() && datas.Count == 1)
             {
-                return (ycd, okd, teachers,datas);
+                return (ycd, okd, teachers,datas,files);
             }
             else {
-                return (ycd, okd, teachers, new List<PushData>());
+                return (ycd, okd, teachers, new List<PushData>(),files);
             }
            
         }
+
+        /// <summary>
+        /// 获取四川省已经上传的。
+        /// </summary>
+        /// <param name="json"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("get-check-size")]
+        public async Task<IActionResult> CheckSize(JsonElement json) 
+        {
+            long size = 0;
+            List<string> schools=  json.GetProperty("schools").ToObject<List<string>>();
+            List<dynamic> schoolData = new List<dynamic>();
+            int schoolFileCount = 0;
+            long schoolFileLength = 0;
+            foreach (var school in schools) 
+            {
+                List<dynamic> teacherData= new List<dynamic>();
+                School  schoolBase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new PartitionKey("Base"));
+                var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher)
+                    .GetList<TeacherTrain>("select value c from  c where c.pk='TeacherTrain'", $"TeacherTrain-{school}");
+                foreach (var teacherTrain in result.list)
+                {
+                    List<dynamic> recordData = new List<dynamic>();
+                    int teacherFileCount = 0;
+                    long teacherFileLength = 0;
+                    foreach (var off in teacherTrain.offlineRecords)
+                    {
+                        string name = $"{off.name}-{off.other.First()?.name}";
+                       
+                        name = Regex.Replace(name, invalidChars, "");
+                         recordData.Add(new { type = "校本研修记录", name, off.url, off.size });
+                        teacherFileCount+=1;
+                        teacherFileLength+=off.size;
+                    }
+                    if (teacherTrain.offlineReport!=null) {
+                        recordData.Add(new { type = "校本研修汇总", name = Regex.Replace(teacherTrain.offlineReport?.name, invalidChars, ""), teacherTrain.offlineReport?.url, teacherTrain.offlineReport?.size });
+                        teacherFileCount+=1;
+                        teacherFileLength+=teacherTrain.offlineReport.size;
+                    }
+                    
+                    foreach (var teacherClass in teacherTrain.teacherClasses)
+                    {
+                        recordData.Add(new { type = "课堂实录", name = Regex.Replace(teacherClass?.name, invalidChars, ""), teacherClass?.url, teacherClass?.size });
+                        teacherFileCount+=1;
+                        teacherFileLength+=teacherClass.size;
+                    }
+                    var resultAbility = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher)
+                        .GetList<AbilitySub>("select value c from  c where c.pk='AbilitySub'", $"AbilitySub-{school}-{teacherTrain.id}");
+                    foreach (var ability in teacherTrain.currency.teacherAilities) {
+                        AbilitySub abilitySub =  await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<AbilitySub>(ability.id, new PartitionKey($"AbilitySub-{school}-{teacherTrain.id}"));
+                        foreach (var upload in abilitySub.uploads)
+                        {
+                            foreach (var url in upload.urls)
+                            {
+                                recordData.Add(new { type = "认证材料",name =$"{ability.no}-{url?.name}", url?.url, url?.size });
+                                teacherFileCount+=1;
+                                teacherFileLength+=url.size;
+                            }
+                        }
+                    }
+                    teacherData.Add(new { id = teacherTrain.id, teacherTrain.nickname, teacherFileCount, teacherFileLength, recordData });
+                }
+                schoolData.Add(new { teachers = teacherData, schoolBase.id, schoolBase.name, schoolFileCount, schoolFileLength });
+                size+=schoolFileLength;
+            }
+            return Ok(new { schoolData , size });
+        }
     }
 
     public class DiagnosisInfoItem

+ 1 - 1
TEAMModelOS/JsonFile/Core/mail.html

@@ -49,7 +49,7 @@
                                         <br>支付金额:<b>{pay_amount}</b>元
                                         <br>购买时间:<b>{pay_time}</b>
                                         <br>发票类型:<b>增值税电子普通发票</b>
-                                        <br>发票代码:<b>{invoiceCode}</b>
+                                        <!--<br>发票代码:<b>{invoiceCode}</b>-->
                                         <br>发票号码:<b>{invoiceNum}</b>
                                         <br>您可以点击“
                                         <a href="{invoiceUrl}" rel="noopener" target="_blank">发票文件下载</a> ”获取该发票文件;

+ 9 - 3
TEAMModelOS/Startup.cs

@@ -110,10 +110,16 @@ namespace TEAMModelOS
             {
                 options.AddPolicy("AllowSpecificOrigin", builder =>
                 {
-                    builder.WithOrigins("https://teammodeltest.blob.core.chinacloudapi.cn", "https://teammodelos.blob.core.chinacloudapi.cn") // 添加允许的源
-                           .AllowAnyMethod() // 允许任何请求方法
+#if DEBUG
+                    builder.AllowAnyOrigin() // 添加允许的源
                            .AllowAnyHeader() // 允许任何请求标头
-                           .AllowCredentials(); // 允许包含凭据
+                           //.AllowCredentials()
+                           ; // 允许包含凭据
+#else
+                    //builder.WithOrigins("https://teammodeltest.blob.core.chinacloudapi.cn",  "https://teammodelos.blob.core.chinacloudapi.cn") // 添加允许的源       .AllowAnyMethod() // 允许任何请求方法
+                    //       .AllowAnyHeader() // 允许任何请求标头
+                    //       .AllowCredentials(); // 允许包含凭据
+#endif            
                 });
             });
             services.AddAzureStorage(Configuration.GetValue<string>("Azure:Storage:ConnectionString"));