更新各班级出勤登记与课评汇总,新增教学日程查询技能与CSP03枚举算法教案
This commit is contained in:
580
.claude/lesson/CSP03/CSP03-08_枚举算法.md
Normal file
580
.claude/lesson/CSP03/CSP03-08_枚举算法.md
Normal file
@@ -0,0 +1,580 @@
|
||||
# CSP03-08 枚举算法
|
||||
|
||||
## 一、课程简介(5分钟)
|
||||
|
||||
### 🎯 课程目标
|
||||
|
||||
1. 理解算法的三种描述方式:自然语言、流程图、伪代码
|
||||
2. 掌握枚举法(穷举法)的核心思想
|
||||
3. 理解枚举法的边界设计原则
|
||||
4. 能够用枚举法解决常见的穷举搜索类问题
|
||||
|
||||
### 📚 核心知识点
|
||||
|
||||
- 算法的描述方式:自然语言(文字说明)、流程图(图形表示)、伪代码(接近代码的文字)
|
||||
- 枚举法的定义:逐一列举所有可能的解,逐个验证
|
||||
- 枚举的范围(边界):如何确定起点和终点
|
||||
- 枚举的验证条件:什么样的值满足要求
|
||||
- 枚举的优化:剪枝、缩小枚举范围
|
||||
- 枚举法的时间复杂度分析
|
||||
|
||||
---
|
||||
|
||||
## 二、知识回顾(10分钟)
|
||||
|
||||
### 👩🏫 教师引导
|
||||
|
||||
> 同学们,我们在 CSP03 前几节学了数组和字符串。从这节课开始,我们进入**算法**的世界!
|
||||
>
|
||||
> 什么是算法?就是解决问题的**方法和步骤**。
|
||||
>
|
||||
> 今天先从最简单的算法思想开始——**枚举法**,也叫穷举法:用最"笨"的方法,把所有可能的答案都试一遍!
|
||||
>
|
||||
> 虽然"笨",但是有效!很多竞赛题用枚举就能解决!
|
||||
|
||||
**互动复习:**
|
||||
|
||||
> - for 循环可以控制变量从 a 到 b 遍历,这不就是在"枚举" a 到 b 的所有值吗?
|
||||
> - 学了枚举法,就相当于给 for 循环赋予了"算法内涵"!
|
||||
|
||||
---
|
||||
|
||||
## 三、新知讲解(45分钟)
|
||||
|
||||
### 1. 新知导入 🎬
|
||||
|
||||
> **猜数游戏:** 我脑子里想了一个 1~100 之间的整数,你能猜出来吗?
|
||||
>
|
||||
> 最"笨"的方法:从 1 猜到 100,总能猜到!——这就是枚举法!
|
||||
>
|
||||
> 实际上,枚举法是很多算法的基础。很多看似复杂的问题,暴力枚举都能解决——只要数据规模不太大。
|
||||
>
|
||||
> 信奥比赛中,枚举法写得好,可以得到部分分甚至满分!
|
||||
|
||||
---
|
||||
|
||||
### 2. 知识点讲解
|
||||
|
||||
#### 2.1 算法的三种描述方式
|
||||
|
||||
**① 自然语言**(文字描述):
|
||||
|
||||
> 找出 1~100 中所有能被 3 整除的数:
|
||||
> 从 1 遍历到 100,对每个数判断能否被 3 整除,若能则输出。
|
||||
|
||||
**② 流程图**(图形表示关键节点和流向):
|
||||
|
||||
```
|
||||
开始
|
||||
↓
|
||||
i = 1
|
||||
↓
|
||||
i <= 100? → 否 → 结束
|
||||
↓ 是
|
||||
i % 3 == 0? → 否 → i++
|
||||
↓ 是
|
||||
输出 i
|
||||
↓
|
||||
i++
|
||||
↓
|
||||
(返回判断)
|
||||
```
|
||||
|
||||
**③ 伪代码**(介于自然语言和代码之间):
|
||||
|
||||
```
|
||||
FOR i FROM 1 TO 100:
|
||||
IF i MOD 3 == 0:
|
||||
OUTPUT i
|
||||
```
|
||||
|
||||
**代码实现:**
|
||||
|
||||
```cpp
|
||||
for (int i = 1; i <= 100; i++) {
|
||||
if (i % 3 == 0) cout << i << " ";
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 2.2 枚举法的核心思想
|
||||
|
||||
**枚举法 = 确定范围 + 逐一验证**
|
||||
|
||||
**三要素:**
|
||||
|
||||
1. **枚举的对象**:什么是我们要找的"候选答案"?
|
||||
2. **枚举的范围(边界)**:候选答案的取值范围?
|
||||
3. **验证的条件**:候选答案满足什么条件才算正确答案?
|
||||
|
||||
---
|
||||
|
||||
#### 2.3 枚举的边界设计
|
||||
|
||||
**原则:宁可多枚举,不要漏掉正确答案!**
|
||||
|
||||
但也要避免枚举太多导致超时。
|
||||
|
||||
**示例:百钱百鸡问题**
|
||||
|
||||
100 文钱买 100 只鸡,鸡翁 5 文/只,鸡母 3 文/只,鸡雏 1 文/3只,三种都要买,各买几只?
|
||||
|
||||
**枚举分析:**
|
||||
|
||||
- 设公鸡 x 只(范围:0 到 20,因为 5×20=100)
|
||||
- 设母鸡 y 只(范围:0 到 33,因为 3×33=99<100)
|
||||
- 小鸡 z = 100 - x - y
|
||||
|
||||
**验证条件:**
|
||||
|
||||
- `z >= 0`(鸡的数量不为负)
|
||||
- `z % 3 == 0`(小鸡必须是 3 的倍数)
|
||||
- `5*x + 3*y + z/3 == 100`(总价格等于 100)
|
||||
|
||||
```cpp
|
||||
for (int x = 0; x <= 20; x++) {
|
||||
for (int y = 0; y <= 33; y++) {
|
||||
int z = 100 - x - y;
|
||||
if (z >= 0 && z % 3 == 0 && 5*x + 3*y + z/3 == 100) {
|
||||
cout << "公鸡:" << x << " 母鸡:" << y << " 小鸡:" << z << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> 📌 黑板推演:两层循环,每次组合验证一种可能。虽然最多循环 21×34=714 次,但逻辑清晰,代码简洁。
|
||||
|
||||
---
|
||||
|
||||
#### 2.4 枚举法的时间复杂度
|
||||
|
||||
| 枚举层数 | 时间复杂度 | 适用规模(n) |
|
||||
|---------|-----------|------------|
|
||||
| 单层枚举 | O(n) | n ≤ 10⁸ |
|
||||
| 双层枚举 | O(n²) | n ≤ 10⁴ |
|
||||
| 三层枚举 | O(n³) | n ≤ 500 |
|
||||
|
||||
> ⚠️ 竞赛中,一般 10⁸ 次操作是 1 秒的上限,超过则可能超时!
|
||||
|
||||
---
|
||||
|
||||
#### 2.5 枚举法的优化(剪枝)
|
||||
|
||||
**剪枝**:在枚举过程中,提前跳过不可能是答案的情况。
|
||||
|
||||
**示例:** 找满足 a + b + c = 100 的正整数组合(a≤b≤c)
|
||||
|
||||
```cpp
|
||||
// 优化前(三层循环):O(n³)
|
||||
for (int a = 1; a <= 100; a++)
|
||||
for (int b = 1; b <= 100; b++)
|
||||
for (int c = 1; c <= 100; c++)
|
||||
if (a + b + c == 100) ...
|
||||
|
||||
// 优化后(剪枝):c = 100 - a - b,直接计算
|
||||
for (int a = 1; a <= 100; a++)
|
||||
for (int b = a; b <= 100; b++) { // b >= a
|
||||
int c = 100 - a - b;
|
||||
if (c >= b) ... // 满足 c >= b 才输出
|
||||
}
|
||||
```
|
||||
|
||||
**效率对比:** 三层循环 100³ = 10⁶ 次;优化后约 10⁴/2 次!
|
||||
|
||||
---
|
||||
|
||||
### 3. GESP 真题演练 ⚡
|
||||
|
||||
**抢答题 1(选择题):**
|
||||
|
||||
> 使用枚举法求 1 到 1000 中所有完全平方数(即某个整数的平方),最合理的枚举方式是( )
|
||||
>
|
||||
> A. 枚举 1~1000 的所有数,判断其是否是某整数的平方
|
||||
> B. 枚举 1~31 的所有整数 i,计算 i² 加入结果
|
||||
> C. 枚举 1~1000 的所有数对 (i, j),判断 i×j 是否满足
|
||||
> D. 随机猜测
|
||||
>
|
||||
> **答案:B**
|
||||
> 解析:√1000 ≈ 31.6,所以枚举 i 从 1 到 31,计算 i² 即可找到 1~1000 内所有完全平方数,效率最高。
|
||||
|
||||
**判断题 2:**
|
||||
|
||||
> 枚举法的核心思想是:逐一检验所有候选答案,找出满足条件的解。( )
|
||||
>
|
||||
> **答案:✓(正确)**
|
||||
|
||||
**抢答题 3:**
|
||||
|
||||
> 以下哪种问题**不适合**用枚举法解决?
|
||||
>
|
||||
> A. 在 1~100 中找满足某条件的整数
|
||||
> B. 在 n=10⁹ 的数组中找出所有满足条件的下标对
|
||||
> C. 在一个 4×4 的棋盘上找所有放置方式
|
||||
> D. 在 1~1000 中找所有质数
|
||||
>
|
||||
> **答案:B**
|
||||
> 解析:n=10⁹ 时,二层枚举需要 10¹⁸ 次,严重超时,需要更高效的算法。
|
||||
|
||||
---
|
||||
|
||||
### 4. 进阶扩展
|
||||
|
||||
**枚举法的经典模板:**
|
||||
|
||||
```cpp
|
||||
// 模板1:单变量枚举
|
||||
for (int x = 起点; x <= 终点; x++) {
|
||||
if (满足条件(x)) {
|
||||
处理答案;
|
||||
}
|
||||
}
|
||||
|
||||
// 模板2:双变量枚举
|
||||
for (int x = 起点1; x <= 终点1; x++) {
|
||||
for (int y = 起点2; y <= 终点2; y++) {
|
||||
if (满足条件(x, y)) {
|
||||
处理答案;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**枚举法的应用领域:**
|
||||
|
||||
- 数字问题(整数分解、质因数)
|
||||
- 组合问题(选 k 个数的方案)
|
||||
- 棋盘问题(八皇后、数独)
|
||||
- 密码暴力破解(有限字符集)
|
||||
|
||||
---
|
||||
|
||||
## 四、课堂练习(45分钟)🎈
|
||||
|
||||
### 练习 1(基础):找因数
|
||||
|
||||
**题目描述:**
|
||||
|
||||
输入一个正整数 n,输出 n 的所有因数(包括 1 和 n 本身),从小到大排列。
|
||||
|
||||
**输入格式:**
|
||||
- 一个正整数 n(1 ≤ n ≤ 10000)
|
||||
|
||||
**输出格式:**
|
||||
- 所有因数,空格分隔
|
||||
|
||||
**样例输入:**
|
||||
```
|
||||
12
|
||||
```
|
||||
|
||||
**样例输出:**
|
||||
```
|
||||
1 2 3 4 6 12
|
||||
```
|
||||
|
||||
**题解代码:**
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
int main() {
|
||||
int n; cin >> n;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
if (n % i == 0) cout << i << " ";
|
||||
}
|
||||
cout << endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 练习 2(基础):判断质数
|
||||
|
||||
**题目描述:**
|
||||
|
||||
输入一个正整数 n,判断它是否是质数(素数)。
|
||||
|
||||
**输入格式:**
|
||||
- 一个正整数 n(2 ≤ n ≤ 10000)
|
||||
|
||||
**输出格式:**
|
||||
- `YES` 或 `NO`
|
||||
|
||||
**样例输入:**
|
||||
```
|
||||
17
|
||||
```
|
||||
|
||||
**样例输出:**
|
||||
```
|
||||
YES
|
||||
```
|
||||
|
||||
**题解代码:**
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
using namespace std;
|
||||
int main() {
|
||||
int n; cin >> n;
|
||||
bool isPrime = true;
|
||||
for (int i = 2; i <= sqrt(n); i++) {
|
||||
if (n % i == 0) { isPrime = false; break; }
|
||||
}
|
||||
cout << (isPrime ? "YES" : "NO") << endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 练习 3(综合):百钱百鸡
|
||||
|
||||
**题目描述:**
|
||||
|
||||
100 文钱买 100 只鸡:公鸡 5 文/只,母鸡 3 文/只,小鸡 1 文/3只,每种至少一只,找出所有购买方案。
|
||||
|
||||
**输入格式:**(无输入)
|
||||
|
||||
**输出格式:**
|
||||
- 每行输出一种方案:`公鸡x只 母鸡y只 小鸡z只`
|
||||
|
||||
**样例输出:**
|
||||
```
|
||||
公鸡4只 母鸡18只 小鸡78只
|
||||
公鸡8只 母鸡11只 小鸡81只
|
||||
公鸡12只 母鸡4只 小鸡84只
|
||||
```
|
||||
|
||||
**题解代码:**
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
int main() {
|
||||
for (int x = 1; x <= 19; x++) {
|
||||
for (int y = 1; y <= 32; y++) {
|
||||
int z = 100 - x - y;
|
||||
if (z > 0 && z % 3 == 0 && 5*x + 3*y + z/3 == 100) {
|
||||
cout << "公鸡" << x << "只 母鸡" << y << "只 小鸡" << z << "只" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 练习 4(综合):找出所有三位水仙花数
|
||||
|
||||
**题目描述:**
|
||||
|
||||
水仙花数是这样的三位数:每一位数字的立方之和等于本身(如 153 = 1³+5³+3³)。输出所有水仙花数。
|
||||
|
||||
**输入格式:**(无)
|
||||
|
||||
**输出格式:**
|
||||
- 每行一个水仙花数
|
||||
|
||||
**样例输出:**(部分)
|
||||
```
|
||||
153
|
||||
370
|
||||
371
|
||||
407
|
||||
```
|
||||
|
||||
**题解代码:**
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
int main() {
|
||||
for (int n = 100; n <= 999; n++) {
|
||||
int a = n / 100; // 百位
|
||||
int b = n / 10 % 10; // 十位
|
||||
int c = n % 10; // 个位
|
||||
if (a*a*a + b*b*b + c*c*c == n) {
|
||||
cout << n << endl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 练习 5(进阶):两数之和
|
||||
|
||||
**题目描述:**
|
||||
|
||||
输入 n 个不同整数和目标值 target,从数组中找出两个数使它们的和等于 target,输出这两个数(先小后大)。保证有且只有一组解。
|
||||
|
||||
**输入格式:**
|
||||
- 第一行 n 和 target
|
||||
- 第二行 n 个整数
|
||||
|
||||
**输出格式:**
|
||||
- 两个整数,空格分隔
|
||||
|
||||
**样例输入:**
|
||||
```
|
||||
5 9
|
||||
2 7 11 15 4
|
||||
```
|
||||
|
||||
**样例输出:**
|
||||
```
|
||||
2 7
|
||||
```
|
||||
|
||||
**题解代码:**
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
int a[1005];
|
||||
int main() {
|
||||
int n, target;
|
||||
cin >> n >> target;
|
||||
for (int i = 1; i <= n; i++) cin >> a[i];
|
||||
for (int i = 1; i <= n; i++) {
|
||||
for (int j = i + 1; j <= n; j++) {
|
||||
if (a[i] + a[j] == target) {
|
||||
int x = min(a[i], a[j]);
|
||||
int y = max(a[i], a[j]);
|
||||
cout << x << " " << y << endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、课堂总结(5分钟)🌟
|
||||
|
||||
> 今天我们学习了算法世界的入门——**枚举法**!
|
||||
>
|
||||
> 枚举法三要素:
|
||||
> 1. **枚举对象**:谁是候选答案?
|
||||
> 2. **枚举范围(边界)**:从哪里到哪里?
|
||||
> 3. **验证条件**:判断当前候选是否正确
|
||||
>
|
||||
> 算法描述方式:自然语言、流程图、伪代码——三种说同一件事,理解即可。
|
||||
>
|
||||
> 下节课我们学"模拟算法"——让计算机按照现实逻辑一步步执行,解决更复杂的问题!
|
||||
|
||||
---
|
||||
|
||||
## 六、课后作业与拓展(10分钟)
|
||||
|
||||
### 📝 课后作业(3道)
|
||||
|
||||
#### 作业 1:输出 n 以内所有质数
|
||||
|
||||
输入正整数 n,输出 2 到 n 之间所有质数,每行一个。
|
||||
|
||||
**样例:** n=10 → 2 3 5 7
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
using namespace std;
|
||||
bool isPrime(int x) {
|
||||
if (x < 2) return false;
|
||||
for (int i = 2; i <= sqrt(x); i++) if (x%i==0) return false;
|
||||
return true;
|
||||
}
|
||||
int main() {
|
||||
int n; cin>>n;
|
||||
for (int i=2;i<=n;i++) if(isPrime(i)) cout<<i<<endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 作业 2:找完全数
|
||||
|
||||
正整数中,"完全数"是所有真因子(不包含本身)之和等于自身的数(如 6 = 1+2+3)。输出 1~1000 内的所有完全数。
|
||||
|
||||
**样例输出:** 6 28 496
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
int main() {
|
||||
for (int n=1;n<=1000;n++) {
|
||||
int sum=0;
|
||||
for (int i=1;i<n;i++) if(n%i==0) sum+=i;
|
||||
if (sum==n) cout<<n<<endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 作业 3:找满足条件的三位数
|
||||
|
||||
找出所有三位整数 n,满足:n 是 3 的倍数,且 n 的各位数字之积也是 3 的倍数。
|
||||
|
||||
**样例输出(部分):** 111 123 ...
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
int main() {
|
||||
for (int n=100;n<=999;n++) {
|
||||
int a=n/100, b=n/10%10, c=n%10;
|
||||
if (n%3==0 && (a*b*c)%3==0) cout<<n<<endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 🔥 拓展习题(尖子生挑战,7道)
|
||||
|
||||
#### 挑战 1:四平方和定理
|
||||
任意正整数都可以表示为最多4个完全平方数之和。对于给定的 n,找出使用最少个完全平方数表示 n 的方案(最少2个,输出具体方案中数量最少的一种)。
|
||||
|
||||
**提示:** 枚举所有 ≤ √n 的完全平方数组合。
|
||||
|
||||
#### 挑战 2:火柴棍数字
|
||||
用 n 根火柴棍可以摆出多少种不同的数字(0-9)?1种数字可以由多根火柴棍组成,请枚举找出可以用恰好 n 根火柴摆出的最大数。(火柴数:0→6,1→2,2→5,3→5,4→4,5→5,6→6,7→3,8→7,9→6)
|
||||
|
||||
**提示:** 动态规划或枚举,但对于简单情况可用枚举。
|
||||
|
||||
#### 挑战 3:扑克牌 24 点
|
||||
给定 4 张牌(1~13),判断能否通过加减乘除(允许括号)得到 24。
|
||||
|
||||
**提示:** 枚举 4 个数的所有排列(4! = 24 种)和运算符的所有组合(4³ = 64 种),以及括号方式(5种),共约 7680 种情况。
|
||||
|
||||
#### 挑战 4:最小覆盖矩形
|
||||
给定平面上 n 个点,找出面积最小的轴对齐矩形,能包含所有点(枚举法:找 x 和 y 方向上的最小最大值)。
|
||||
|
||||
**提示:** 找 min_x, max_x, min_y, max_y,面积即 (max_x-min_x)*(max_y-min_y)。
|
||||
|
||||
#### 挑战 5:质因数分解
|
||||
输入正整数 n,输出其质因数分解结果(如 12 = 2² × 3)。
|
||||
|
||||
**提示:** 从 2 开始枚举,能整除就统计个数并除去,直到 n == 1 或当前枚举数的平方大于 n。
|
||||
|
||||
#### 挑战 6:最小公倍数与最大公因数
|
||||
枚举法求两个整数 a、b 的最大公因数(GCD):枚举 1~min(a,b),找最大的能同时整除两者的数。
|
||||
|
||||
**提示:** 理解辗转相除法(Euclid算法)其实更优,但枚举在数值小时完全可行。
|
||||
|
||||
#### 挑战 7:找所有满足条件的数组
|
||||
给定 n(1≤n≤10),找出所有满足:长度为 n、元素均为 1 到 9、所有元素之积等于给定值 M 的严格递增序列。
|
||||
|
||||
**提示:** 递归枚举,每次选一个比上一个大的数,在乘积不超过 M 的情况下继续。
|
||||
@@ -9,3 +9,4 @@
|
||||
| 2026-04-11 | AI大作家(上) | 第5课 | ✅ 出勤 | |
|
||||
| 2026-04-17 | AI大作家(下) | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-18 | 我是大作家-2 | 第6课 | ⏸ 请假 | |
|
||||
| 2026-05-02 | 个人网页完善 | 第8课 | ⏸ 请假 | |
|
||||
|
||||
@@ -10,3 +10,4 @@
|
||||
| 2026-04-12 | 我是大作家(完结篇) | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-18 | AI大作家插图生成 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-04-25 | 我的个人主页 | 第8课 | ✅ 出勤 | |
|
||||
| 2026-05-03 | 我的个人主页(下) | 第9课 | ⏸ 请假 | |
|
||||
|
||||
@@ -10,3 +10,4 @@
|
||||
| 2026-04-12 | 我是大作家(完结篇) | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-18 | AI大作家插图生成 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-04-25 | 我的个人主页 | 第8课 | ✅ 出勤 | |
|
||||
| 2026-04-26 | 个人网页完善 | 第9课 | ✅ 出勤 | |
|
||||
|
||||
@@ -94,3 +94,26 @@
|
||||
老师会继续关注子墨的表现,期待看到更多精彩!🌟💡
|
||||
|
||||
---
|
||||
|
||||
## 第8条:个人网页完善
|
||||
|
||||
**授课日期**:2026-04-26
|
||||
|
||||
**课评内容**:
|
||||
|
||||
子墨今天表现超棒~对个人网页完善的知识点掌握得很不错~能够把自己的头像引入到网页中,还锲而不舍地成功添加了自己喜欢的背景音乐,这种坚持达成目标的精神特别好!以你的机灵程度,把学到的知识灵活运用起来的能力真的很厉害~要是上课的时候能再专注一点,少被周围的事情分散注意力,你一定会做出更有创意的作品哦~
|
||||
老师会继续关注子墨的表现,期待看到更多精彩!🌟💡
|
||||
|
||||
---
|
||||
|
||||
## 第9条:我的个人主页(下)
|
||||
|
||||
**授课日期**:2026-05-03
|
||||
|
||||
**课评内容**:
|
||||
|
||||
子墨今天表现超棒!不仅完成了个人网页的完善任务,还成功把自己的头像加入到了网页中,最值得表扬的是你锲而不舍地反复尝试,最终成功把自己喜欢的音乐也添加到了网页里,这种坚持达成目标的精神特别厉害!你对AI工具的灵活运用能力一直都很强,要是上课的时候能再专注一点,少被周围的事情分散注意力,一定会做出更有创意的作品哦~
|
||||
|
||||
老师会继续关注子墨的表现,期待看到更多精彩!🌟💡
|
||||
|
||||
---
|
||||
|
||||
@@ -10,3 +10,4 @@
|
||||
| 2026-04-12 | 我是大作家(完结篇) | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-18 | AI大作家插图生成 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-04-25 | 我的个人主页 | 第8课 | ✅ 出勤 | |
|
||||
| 2026-04-26 | 个人网页完善 | 第9课 | ✅ 出勤 | |
|
||||
|
||||
@@ -94,3 +94,26 @@
|
||||
老师会继续关注俊研的进步,期待看到更多精彩!🌸😊
|
||||
|
||||
---
|
||||
|
||||
## 第8条:个人网页完善
|
||||
|
||||
**授课日期**:2026-04-26
|
||||
|
||||
**课评内容**:
|
||||
|
||||
俊研今天表现超棒~对个人网页完善的知识点掌握得很不错~上课一直安静专注,不仅完成了网页生成,还通过自己的方法把网页设计成喜欢的样式,还添加了自己喜欢的变形金刚电影元素,很有自己的想法~你踏实认真的学习态度一直都很棒,要是课后多练习一下打字,创作的效率会更高哦~
|
||||
老师会继续关注俊研的进步,期待看到更多精彩!🌸😊
|
||||
|
||||
---
|
||||
|
||||
## 第9条:我的个人主页(下)
|
||||
|
||||
**授课日期**:2026-05-03
|
||||
|
||||
**课评内容**:
|
||||
|
||||
俊研今天表现超棒!对个人网页完善的知识点掌握得很不错,上课一直安静专注,不仅完成了网页生成,还通过自己的方法把网页设计成喜欢的样式,还添加了自己喜欢的变形金刚电影元素,很有自己的想法~你踏实认真的学习态度一直都很棒,要是课后多练习一下打字,创作的效率会更高哦~
|
||||
|
||||
老师会继续关注俊研的进步,期待看到更多精彩!🌸😊
|
||||
|
||||
---
|
||||
|
||||
@@ -8,4 +8,5 @@
|
||||
| 2026-03-29 | 我是大作家-1 | 第4课 | ✅ 出勤 | |
|
||||
| 2026-04-06 | 我是大作家-2 | 第5课 | ✅ 出勤 | |
|
||||
| 2026-04-12 | 我是大作家(完结篇) | 第6课 | ⏸ 请假 |
|
||||
| 2026-04-18 | AI大作家插图生成 | 第7课 | ⏸ 请假 | | |
|
||||
| 2026-04-18 | AI大作家插图生成 | 第7课 | ⏸ 请假 | |
|
||||
| 2026-04-26 | 个人网页完善 | 第8课 | ✅ 出勤 | |
|
||||
|
||||
@@ -82,3 +82,26 @@
|
||||
嘉博本周请假,未上课。请嘉博家长安排好时间,督促嘉博在家了解本周小说插图生成的相关知识点,包括使用trea生成插图提示词、使用豆包生成图片并插入文章的方法。如有疑问,欢迎随时联系老师。
|
||||
|
||||
---
|
||||
|
||||
## 第7条:个人网页完善
|
||||
|
||||
**授课日期**:2026-04-26
|
||||
|
||||
**课评内容**:
|
||||
|
||||
嘉博今天表现超棒~对个人网页完善的知识点有很好的掌握~上课一直很专注,对自己创建的个人网页特别感兴趣,能够详细描述自己的兴趣爱好、梦想给AI,还能主动修改卡片颜色、给背景添加小花,很有自己的创意~虽然打字速度还是需要慢慢提升,但你一直在认真坚持,这份细致的态度特别珍贵~要是课后可以多练习一下打字,你创作的效率会更高哦~
|
||||
老师会继续关注嘉博的表现,期待看到更多精彩!🌟💡
|
||||
|
||||
---
|
||||
|
||||
## 第8条:我的个人主页(下)
|
||||
|
||||
**授课日期**:2026-05-03
|
||||
|
||||
**课评内容**:
|
||||
|
||||
嘉博今天对自己的个人网页特别用心,上课很开心~能够详细地把自己的兴趣爱好、梦想告诉AI,表达得很清楚!看到页面觉得颜色不太好看,就主动修改卡片颜色,还给背景添加了小花,这种根据自己的审美进行优化的意识很棒~你对网页细节的关注说明你很有设计眼光,继续发挥创意,你的网页会越来越精彩的!
|
||||
|
||||
老师会继续关注嘉博的表现,期待看到更多精彩!🌟💡
|
||||
|
||||
---
|
||||
|
||||
@@ -9,4 +9,5 @@
|
||||
| 2026-04-05 | 我是大作家-2 | 第5课 | ⏸ 请假 | 已转班 |
|
||||
| 2026-04-12 | 我是大作家(完结篇) | 第6课 | ⏸ 请假 | 已转班
|
||||
| 2026-04-18 | AI大作家插图生成 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-04-25 | 我的个人主页 | 第8课 | ✅ 出勤 | | |
|
||||
| 2026-04-25 | 我的个人主页 | 第8课 | ✅ 出勤 | |
|
||||
| 2026-05-03 | 我的个人主页(下) | 第9课 | ✅ 出勤 | |
|
||||
|
||||
@@ -92,3 +92,15 @@
|
||||
老师会继续关注彦棋的表现,期待看到更多惊喜!🎯✨
|
||||
|
||||
---
|
||||
|
||||
## 第8条:我的个人主页(下)
|
||||
|
||||
**授课日期**:2026-05-03
|
||||
|
||||
**课评内容**:
|
||||
|
||||
彦棋今天状态超棒!按照老师的要求顺利完成了个人网页的完善任务,成功给自己的作品添加了头像和喜欢的音乐,动手能力很强~老师觉得你在AIGC创作方面很有天赋,非常推荐你参加后续的AIGC比赛,展示你的才华!以你的能力,只要更细心一点,把作品的每个细节都打磨得更精致,一定会有更惊艳的表现~
|
||||
|
||||
老师会继续关注彦棋的表现,期待看到更多惊喜!🎯✨
|
||||
|
||||
---
|
||||
|
||||
@@ -10,3 +10,4 @@
|
||||
| 2026-04-12 | 我是大作家(完结篇) | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-19 | AI大作家插图生成 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-04-26 | 我的个人主页 | 第8课 | ✅ 出勤 | |
|
||||
| 2026-05-04 | 我的个人主页(下) | 第9课 | ✅ 出勤 | |
|
||||
|
||||
@@ -92,3 +92,15 @@
|
||||
要是能继续保持这种认真的学习态度,不被周围的事情吸引,效果会更好~老师会继续关注皓霖的学习状态,期待看到更多进步!🌟💪
|
||||
|
||||
---
|
||||
|
||||
## 第8条:我的个人主页(下)
|
||||
|
||||
**授课日期**:2026-05-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
皓霖今天表现很棒!对本节课的知识掌握得很好,个人主页作品也完成得很出色~特别让老师高兴的是,皓霖上课的状态特别好,能够在老师讲课的时候放下手上的任务,认真听老师的安排,这种能够自我管理的专注力比之前进步了很多!继续保持这种认真的学习态度,你的效率会越来越高的~
|
||||
|
||||
老师会继续关注皓霖的表现,期待看到更多进步!🌟💪
|
||||
|
||||
---
|
||||
|
||||
@@ -10,3 +10,4 @@
|
||||
| 2026-04-12 | 我是大作家(完结篇) | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-19 | AI大作家插图生成 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-04-26 | 我的个人主页 | 第8课 | ✅ 出勤 | |
|
||||
| 2026-05-04 | 我的个人主页(下) | 第9课 | ⏸ 请假 | |
|
||||
|
||||
@@ -74,3 +74,15 @@
|
||||
你的踏实认真让老师很省心,继续保持这份专注和独立完成任务的态度~老师会继续关注翊弘的表现,期待看到更多精彩!🌟💡
|
||||
|
||||
---
|
||||
|
||||
## 第7条:我的个人主页(下)
|
||||
|
||||
**授课日期**:2026-05-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
翊弘今天表现很棒!对本节课的知识掌握得很好,个人网页做得非常出色,上课状态也一直很稳定,能够踏踏实实地完成每个步骤,遇到问题也能自己思考解决~你一直都是个认真踏实的孩子,继续保持这份专注和独立完成任务的态度,一定会越来越优秀的!
|
||||
|
||||
老师会继续关注翊弘的表现,期待看到更多精彩!🌟💡
|
||||
|
||||
---
|
||||
|
||||
@@ -92,3 +92,15 @@
|
||||
老师会继续关注浩宸的学习状态,期待看到更多进步!🌟💪
|
||||
|
||||
---
|
||||
|
||||
## 第8条:我的个人主页(下)
|
||||
|
||||
**授课日期**:2026-05-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
浩宸今天整体表现不错,在老师的引导下完成了个人网页的完善任务,对网页添加元素的操作有了进一步的掌握~老师看到你一直在努力跟上节奏,这一点值得肯定。如果上课的时候能够更专注一点,主动跟着老师的思路走,遇到问题大胆提问,学习效果一定会更好。打字不熟练没关系,多练习就会越来越快的,四年级的男子汉,老师相信你一定可以做到的!
|
||||
|
||||
老师会继续关注浩宸的学习状态,期待看到更多进步!🌟💪
|
||||
|
||||
---
|
||||
|
||||
@@ -78,3 +78,15 @@
|
||||
你的学习状态一直很好,接受新知识又快又认真,继续保持这种积极好学的态度~老师会继续关注浩睿的表现,期待看到更多精彩!✨💡
|
||||
|
||||
---
|
||||
|
||||
## 第7条:我的个人主页(下)
|
||||
|
||||
**授课日期**:2026-05-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
浩睿今天表现超棒!对本节课的知识点掌握得相当出色,还能够举一反三,灵活运用学到的方法来完善自己的个人网页,这种学习能力特别厉害!你一直都很有探索精神,遇到问题会主动思考解决方法,学习效率很高。继续保持这份积极好学的态度,你一定可以在AIGC创作方面取得更多的成果!
|
||||
|
||||
老师会继续关注浩睿的表现,期待看到更多创意!✨💡
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# 张玉辰 课评汇总(2026春季)
|
||||
|
||||
**班级**:周日下午1400AI03班
|
||||
**学生**:张玉辰
|
||||
|
||||
---
|
||||
|
||||
## 第1条:我的个人主页(下)
|
||||
|
||||
**授课日期**:2026-05-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
玉辰今天第一次上课表现就很不错!成功完成了自己的个人网页,还顺利给自己的网页添加了头像,遇到问题会主动询问老师,这种勤学好问的态度特别棒!看得出来你对AIGC创作很感兴趣,继续保持这份热情,跟着老师的节奏一步步学习,一定会越来越厉害的。
|
||||
|
||||
老师会继续关注玉辰的表现,期待看到更多精彩!🌟💡
|
||||
|
||||
---
|
||||
@@ -0,0 +1,5 @@
|
||||
# 出勤登记 - 2026春季学期
|
||||
|
||||
| 日期 | 课程 | 课次 | 状态 | 备注 |
|
||||
|------|------|------|------|------|
|
||||
| 2026-05-04 | 我的个人主页(下) | 第9课 | ⏸ 请假 | |
|
||||
@@ -76,3 +76,15 @@
|
||||
你的想象力和耐心一直都是你的优势,今天把它们都用在了网页创作上,作品完成得很出色~老师会继续关注俊宇的表现,期待看到更多惊喜!🎯✨
|
||||
|
||||
---
|
||||
|
||||
## 第7条:我的个人主页(下)
|
||||
|
||||
**授课日期**:2026-05-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
俊宇今天表现太棒了!全程跟着老师的节奏走,对自己的作品特别上心,不仅积极完成了所有任务,还主动和老师互动交流想法,进步非常明显,老师也发现你越来越出色了!你在AIGC创作方面很有天赋,老师特别推荐你参加后续的AIGC比赛,相信你一定可以取得好成绩的。继续保持这份热情和专注,你会越来越厉害的!
|
||||
|
||||
老师会继续关注俊宇的表现,期待看到更多惊喜!🎯✨
|
||||
|
||||
---
|
||||
|
||||
@@ -76,3 +76,15 @@
|
||||
老师会继续关注楚悦的表现,期待看到更多精彩!🌟💡
|
||||
|
||||
---
|
||||
|
||||
## 第7条:我的个人主页(下)
|
||||
|
||||
**授课日期**:2026-05-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
楚悦今天表现很棒!不仅补上了上节课请假落下的内容,还成功给自己的个人网页添加了头像,动手能力很强~老师知道你看到很多字要打会有些害怕,没关系,打字是可以慢慢练习的,回家之后可以下载一个金山打字软件,每天练习10分钟,坚持一段时间,打字速度一定会越来越快的。你一直都很认真踏实,继续保持这份学习态度,一定会越来越优秀的!
|
||||
|
||||
老师会继续关注楚悦的进步,期待看到更多精彩!🌸😊
|
||||
|
||||
---
|
||||
|
||||
@@ -8,3 +8,5 @@
|
||||
| 2026-03-29 | 连续性元素处理 | 第5课 | ⏸ 请假 | |
|
||||
| 2026-04-05 | 字符数组 | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-18 | 字符串处理 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-04-25 | 字符串小测与复习 | 第8课 | ✅ 出勤 | |
|
||||
| 2026-05-02 | 枚举算法 | 第9课 | ✅ 出勤 | |
|
||||
|
||||
@@ -101,3 +101,24 @@
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第9条:枚举算法
|
||||
|
||||
**授课日期**:2026-05-02
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《枚举算法》:
|
||||
1. 理解算法的三种描述方式:自然语言、流程图、伪代码
|
||||
2. 掌握枚举法(穷举法)的核心思想:确定范围+逐一验证
|
||||
3. 理解枚举法的边界设计原则,合理设置枚举范围
|
||||
4. 掌握枚举法的优化策略(剪枝),减少不必要的枚举
|
||||
5. 学会枚举法的代码实现,能够将枚举思想转化为程序代码
|
||||
|
||||
此外,课前对上周string知识点进行了小测复习,重点回顾了字符串长度函数(size()/length())、下标访问、substr()截取、find()查找、replace()替换、erase()删除等基础函数的用法。
|
||||
|
||||
林轩这节课表现得还不错,对枚举算法有所了解,能够掌握枚举的核心思想,求约数、判断素数等基础题目可以自己完成。上课时能合上电脑跟着老师学习,这一点有进步!不过在做"两数之和"时会有一点粗心,回去可以重新写一次第五题巩固一下。从课前小测来看,substr()截取、replace()替换和erase()删除这几个函数的用法还需要多复习,回去把这几个函数的参数含义整理到笔记本上,理解清楚就不会再丢分了。
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
@@ -8,3 +8,5 @@
|
||||
| 2026-03-29 | 连续性元素处理 | 第5课 | ⏸ 请假 | |
|
||||
| 2026-04-05 | 字符数组 | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-18 | 字符串处理 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-04-25 | 字符串小测与复习 | 第8课 | ✅ 出勤 | |
|
||||
| 2026-05-02 | 枚举算法 | 第9课 | ✅ 出勤 | |
|
||||
|
||||
@@ -99,3 +99,24 @@
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第9条:枚举算法
|
||||
|
||||
**授课日期**:2026-05-02
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《枚举算法》:
|
||||
1. 理解算法的三种描述方式:自然语言、流程图、伪代码
|
||||
2. 掌握枚举法(穷举法)的核心思想:确定范围+逐一验证
|
||||
3. 理解枚举法的边界设计原则,合理设置枚举范围
|
||||
4. 掌握枚举法的优化策略(剪枝),减少不必要的枚举
|
||||
5. 学会枚举法的代码实现,能够将枚举思想转化为程序代码
|
||||
|
||||
此外,课前对上周string知识点进行了小测复习,重点回顾了字符串长度函数(size()/length())、下标访问、substr()截取、find()查找、replace()替换、erase()删除等基础函数的用法。
|
||||
|
||||
俊宇本节课整体表现不错,对枚举算法有所了解,能够掌握相关内容,题目也可以自己独立完成,甚至还能发现一些优化方法,做完优化之后又用传统方法再写一次,这种对比学习的思维方式特别棒!不过会有一点点吵,会发出一些奇怪的声音,被老师批评之后可以立刻改正,继续完成自己的作业,这个态度值得肯定。从课前小测来看,substr()截取函数的参数含义和字符串比较的规则还需要再巩固一下,回去把这两个知识点理一理,记清楚就不会出错了。
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
@@ -8,3 +8,5 @@
|
||||
| 2026-03-29 | 连续性元素处理 | 第5课 | ⏸ 请假 | |
|
||||
| 2026-04-05 | 字符数组 | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-18 | 字符串处理 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-04-25 | 字符串小测与复习 | 第8课 | ✅ 出勤 | |
|
||||
| 2026-05-02 | 枚举算法 | 第9课 | ✅ 出勤 | |
|
||||
|
||||
@@ -99,3 +99,24 @@
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第9条:枚举算法
|
||||
|
||||
**授课日期**:2026-05-02
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《枚举算法》:
|
||||
1. 理解算法的三种描述方式:自然语言、流程图、伪代码
|
||||
2. 掌握枚举法(穷举法)的核心思想:确定范围+逐一验证
|
||||
3. 理解枚举法的边界设计原则,合理设置枚举范围
|
||||
4. 掌握枚举法的优化策略(剪枝),减少不必要的枚举
|
||||
5. 学会枚举法的代码实现,能够将枚举思想转化为程序代码
|
||||
|
||||
此外,课前对上周string知识点进行了小测复习,重点回顾了字符串长度函数(size()/length())、下标访问、substr()截取、find()查找、replace()替换、erase()删除等基础函数的用法。
|
||||
|
||||
子杰本节课表现整体不错,对枚举算法有所了解,能够掌握相关内容,基础题目可以自己完成。不过到后面的"百钱百鸡"、"水仙花数"等综合题目时会有一点点卡壳,在老师的指导下能够重新理顺思路完成题目,这种不放弃的精神很好。子杰这学期的态度进步非常大,主动性也越来越强,继续保持!从课前小测来看,find()查找函数的返回值含义和replace()替换函数的用法还需要多花点时间巩固,回去把这些函数整理到笔记本上,多练习几遍就熟练了。
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
@@ -8,3 +8,4 @@
|
||||
| 2026-03-29 | 连续性元素处理 | 第5课 | ⏸ 请假 | |
|
||||
| 2026-04-05 | 字符数组 | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-18 | 字符串处理 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-05-03 | 枚举算法 | 第9课 | ✅ 出勤 | |
|
||||
|
||||
@@ -99,3 +99,22 @@
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第9条:枚举算法
|
||||
|
||||
**授课日期**:2026-05-02
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《枚举算法》:
|
||||
1. 掌握使用自然语言、流程图、伪代码描述算法的方法
|
||||
2. 理解枚举法的概念与思想,掌握枚举法的基本实现方式
|
||||
3. 学会枚举法的边界确定,能够合理设置枚举范围
|
||||
4. 掌握枚举法的优化策略,能够减少不必要的枚举
|
||||
5. 学会枚举法的代码实现,能够将枚举思想转化为程序代码
|
||||
|
||||
明泓课堂练习能够全部完成,对枚举算法的知识点也能够掌握,学习能力一如既往地在线!不过老师发现明泓偶尔会打开游戏进行游玩,虽然在老师的要求下能够及时关闭继续学习,但还是希望明泓上课时能够更加专注,把全部精力放在课堂上。六年级的知识点会越来越有难度,专注听课才能理解得更透彻。
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
@@ -8,3 +8,5 @@
|
||||
| 2026-03-29 | 连续性元素处理 | 第5课 | ⏸ 请假 | |
|
||||
| 2026-04-05 | 字符数组 | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-18 | 字符串处理 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-04-25 | 字符串小测与复习 | 第8课 | ✅ 出勤 | |
|
||||
| 2026-05-02 | 枚举算法 | 第9课 | ✅ 出勤 | |
|
||||
|
||||
@@ -101,3 +101,24 @@
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第9条:枚举算法
|
||||
|
||||
**授课日期**:2026-05-02
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《枚举算法》:
|
||||
1. 理解算法的三种描述方式:自然语言、流程图、伪代码
|
||||
2. 掌握枚举法(穷举法)的核心思想:确定范围+逐一验证
|
||||
3. 理解枚举法的边界设计原则,合理设置枚举范围
|
||||
4. 掌握枚举法的优化策略(剪枝),减少不必要的枚举
|
||||
5. 学会枚举法的代码实现,能够将枚举思想转化为程序代码
|
||||
|
||||
此外,课前对上周string知识点进行了小测复习,重点回顾了字符串长度函数(size()/length())、下标访问、substr()截取、find()查找、replace()替换、erase()删除等基础函数的用法。
|
||||
|
||||
锦程对本节课枚举算法有所了解,能够掌握相关的内容,整体表现不错,特别积极!对枚举法"确定范围、逐一验证、验证条件"三个要素理解得比较到位,求约数和判断素数的题目都能顺利完成。锦程的学习状态一直很稳定,基础也打得扎实。从课前小测来看,字符串比较的规则还需要再巩固一下,特别是"123"和"4"的比较结果容易搞混——字符串比较是逐位比ASCII码,不是比数值大小,这个细节注意一下就不会再丢分了。希望锦程在掌握基础的前提下,尝试挑战更有深度的内容。
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
@@ -8,3 +8,4 @@
|
||||
| 2026-03-29 | 连续性元素处理 | 第5课 | ⏸ 请假 | |
|
||||
| 2026-04-05 | 字符数组 | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-18 | 字符串处理 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-05-03 | 枚举算法 | 第9课 | ⏸ 请假 | |
|
||||
|
||||
@@ -8,3 +8,5 @@
|
||||
| 2026-03-29 | 连续性元素处理 | 第5课 | ⏸ 请假 | |
|
||||
| 2026-04-05 | 字符数组 | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-18 | 字符串处理 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-04-25 | 字符串小测与复习 | 第8课 | ✅ 出勤 | |
|
||||
| 2026-05-01 | 枚举算法 | 第9课 | ✅ 出勤 | |
|
||||
|
||||
@@ -1,96 +1,70 @@
|
||||
# 张雨禾 课评汇总(2026春季)
|
||||
|
||||
**班级**:周六下午1400CSP03班
|
||||
**学生**:张雨禾
|
||||
|
||||
---
|
||||
|
||||
## 第1条:一二级知识回顾
|
||||
|
||||
**授课日期**:2026-03-08
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,我们本周复习的主题是《一二级知识回顾》
|
||||
|
||||
1. 复习数据类型
|
||||
2. 复习循环结构
|
||||
|
||||
**课堂反馈**:
|
||||
|
||||
开学第一节课,雨禾对上学期的知识还记忆犹新,解题游刃有余!但细节处理还不够好,容易失分,后续老师会引导雨禾改正,记得完成拓展练习喔~老师会继续关注雨禾的进步!🌟✨
|
||||
|
||||
---
|
||||
|
||||
## 第2条:数组计数
|
||||
|
||||
**授课日期**:2026-03-28
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《数组计数》:
|
||||
1. 数组的定义与初始化
|
||||
2. 数组遍历方法
|
||||
3. 计数器原理
|
||||
4. 数组下标运用
|
||||
5. 算法思维培养
|
||||
|
||||
雨禾这节课比较认真,能跟上老师的节奏。不过老师发现雨禾做题的时候比较粗心,容易出现一些小错误。希望雨禾做题的时候能更细心一些,多检查几遍,减少粗心的失误~
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第3条:字符数组
|
||||
|
||||
**授课日期**:2026-04-05
|
||||
|
||||
**课评内容**:
|
||||
|
||||
雨禾每次都能在周六下午前把作业做完,时间管理能力和学习主动性让老师很欣慰~能够跟上老师的节奏上课,对本周字符数组的知识点有一定掌握。
|
||||
|
||||
不过老师发现,雨禾后续没有再继续做题练习,一个星期不做题会导致很多知识点遗忘。编程是需要持续练习的技能,希望雨禾回去之后能够每天抽出一些时间复习巩固,保持对代码的熟练度。理解为什么这么写,不只是做完就好~
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第7条:字符串处理
|
||||
|
||||
**授课日期**:2026-04-18
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《字符串处理》:
|
||||
1. 学习getline()函数的使用,掌握读取一整行字符串的方法
|
||||
2. 学习substr()函数,理解字符串截取的方法和参数含义
|
||||
3. 学习size() / length()函数,掌握获取字符串长度的方法
|
||||
4. 学习find()函数,理解字符串查找的原理和返回值
|
||||
5. 培养学生对字符串处理的综合应用能力和编程思维
|
||||
|
||||
张雨禾上课对知识掌握不错,下课也积极把作业完成,态度很认真。不过老师发现过去七天雨禾很多知识点都不太记得了,说明课后复习还需要加强。希望雨禾回去把本周的知识点手写记录到笔记本上,并且每天花一点时间复习。辛苦雨禾爸爸周一到周五进行监督,帮助雨禾养成好习惯。
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第8条:字符串小测与复习
|
||||
|
||||
**授课日期**:2026-04-25
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周我们进行了字符串知识点的小测与复习,主要内容包括:
|
||||
1. 字符串函数的复习与巩固
|
||||
2. 字符数组下标的使用规则
|
||||
3. 大小写区分等基础知识点回顾
|
||||
4. 代码填空练习巩固知识
|
||||
5. 复习习惯的培养与强化
|
||||
|
||||
雨禾本周表现有惊喜也有需要加强的地方:惊喜的是在代码填空中,雨禾对之前的知识掌握得很不错,比如大小写区分的知识点能够准确写出来,说明基础打得很扎实;需要加强的是对上节课学过的字符串函数记忆不够牢固,容易忘记,字符数组下标的知识点也有所欠缺。
|
||||
|
||||
雨禾的学习态度一直很认真,这是非常好的品质。老师建议你回去之后把笔记认真抄一遍,重点记清楚每个函数的作用和用法,每天花10-15分钟复习一下这些知识点,多练习就能记牢了。以你的认真程度,只要坚持复习,一定能把这些知识点掌握得很扎实!
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
## 第9条:枚举算法
|
||||
**授课日期**:2026-05-01
|
||||
**课评内容**:
|
||||
家长好,本周学习的内容是《枚举算法》:
|
||||
1. 掌握使用自然语言、流程图、伪代码描述算法的方法
|
||||
2. 理解枚举法的概念与思想,掌握枚举法的基本实现方式
|
||||
3. 学会枚举法的边界确定,能够合理设置枚举范围
|
||||
4. 掌握枚举法的优化策略,能够减少不必要的枚举
|
||||
5. 学会枚举法的代码实现,能够将枚举思想转化为程序代码
|
||||
雨禾对本节课的枚举算法掌握得很不错!本节课的难度相较于上节课有所放缓,雨禾学习得也更加从容,能够独立完成所有题目,表现非常好,老师为你感到骄傲!
|
||||
希望雨禾回去之后继续保持认真的学习态度,每天花10-15分钟复习巩固本节课的枚举算法知识点,养成及时复习的好习惯,减少知识点遗忘。做题的时候可以多检查几遍,慢慢养成细心的习惯,减少不必要的失误。继续加油,你一定会越来越优秀的!
|
||||
加油呀!💪✨
|
||||
---
|
||||
@@ -8,3 +8,5 @@
|
||||
| 2026-03-29 | 连续性元素处理 | 第5课 | ⏸ 请假 | |
|
||||
| 2026-04-05 | 字符数组 | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-18 | 字符串处理 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-04-25 | 字符串小测与复习 | 第8课 | ✅ 出勤 | |
|
||||
| 2026-05-01 | 枚举算法 | 第9课 | ✅ 出勤 | |
|
||||
|
||||
@@ -1,96 +1,70 @@
|
||||
# 苏俊宇 课评汇总(2026春季)
|
||||
|
||||
**班级**:周六下午1400CSP03班
|
||||
**学生**:苏俊宇
|
||||
|
||||
---
|
||||
|
||||
## 第1条:一二级知识回顾
|
||||
|
||||
**授课日期**:2026-03-08
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,我们本周复习的主题是《一二级知识回顾》
|
||||
|
||||
1. 复习数据类型
|
||||
2. 复习循环结构
|
||||
|
||||
**课堂反馈**:
|
||||
|
||||
开学第一课俊宇状态回来啦!能沉下心学习,上学期有些漏洞,这学期老师会继续关注俊宇,一起把基础补扎实,跟上节奏!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第2条:数组计数
|
||||
|
||||
**授课日期**:2026-03-28
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《数组计数》:
|
||||
1. 数组的定义与初始化
|
||||
2. 数组遍历方法
|
||||
3. 计数器原理
|
||||
4. 数组下标运用
|
||||
5. 算法思维培养
|
||||
|
||||
俊宇这节课上课比较认真,对以前的知识点能够有理解。并且能快速告诉老师自己的理解。但是如果是代码的话,他就根本做不出来,不知道该怎么做。希望俊宇回去多多练习,把理解和实践结合起来,多动手写代码才能真正掌握~
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第3条:字符数组
|
||||
|
||||
**授课日期**:2026-04-05
|
||||
|
||||
**课评内容**:
|
||||
|
||||
苏俊宇本周状态有所回暖,表现不错!在一些思维题上,能够告诉老师怎么写,说明对解题过程是有理解的,这份思考能力很可贵~上课态度也很积极,没有表现出不想写代码的情绪,让老师看到了你的进步!
|
||||
|
||||
不过目前在代码实现方面还有些欠缺,知道了思路但不太能够写出来。希望苏俊宇回去之后必须认真完成作业,多多练习,把思维能力和代码能力结合起来。理解为什么这么写,不只是知道思路就好~
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第7条:字符串处理
|
||||
|
||||
**授课日期**:2026-04-18
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《字符串处理》:
|
||||
1. 学习getline()函数的使用,掌握读取一整行字符串的方法
|
||||
2. 学习substr()函数,理解字符串截取的方法和参数含义
|
||||
3. 学习size() / length()函数,掌握获取字符串长度的方法
|
||||
4. 学习find()函数,理解字符串查找的原理和返回值
|
||||
5. 培养学生对字符串处理的综合应用能力和编程思维
|
||||
|
||||
苏俊宇状态在线,表现积极,能够了解本周字符串语法,上课也很认真,紧跟老师节奏,对于一些思路能很清楚地记录,态度端正。希望俊宇在完成速度上再多加练习,让写代码的能力也跟上理解的速度,多多练习会更熟练的。
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第8条:字符串小测与复习
|
||||
|
||||
**授课日期**:2026-04-25
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周我们进行了字符串知识点的小测与复习,主要内容包括:
|
||||
1. 字符数组与字符串的声明方法
|
||||
2. 字符串相关函数的使用与区别
|
||||
3. 字符串基本操作的实践
|
||||
4. 笔记研读与知识点巩固方法
|
||||
5. 动手练习习惯的培养
|
||||
|
||||
从课堂小测结果来看,俊宇对字符数组的声明掌握得不错,这部分基础打得很扎实!但是对于字符串的一些相关函数记忆还不够牢固,需要回去把笔记认真研读,反复尝试运用,才能真正掌握。
|
||||
|
||||
俊宇的数学基础很好,逻辑思维能力很强,这对于学习编程是很大的优势。编程和数学其实是相通的,都是用逻辑来解决问题,只要你多花点时间动手练习,把这些函数的用法记牢,写代码的能力一定会越来越强的。老师相信你有这个能力,加油!
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
## 第9条:枚举算法
|
||||
**授课日期**:2026-05-01
|
||||
**课评内容**:
|
||||
家长好,本周学习的内容是《枚举算法》:
|
||||
1. 掌握使用自然语言、流程图、伪代码描述算法的方法
|
||||
2. 理解枚举法的概念与思想,掌握枚举法的基本实现方式
|
||||
3. 学会枚举法的边界确定,能够合理设置枚举范围
|
||||
4. 掌握枚举法的优化策略,能够减少不必要的枚举
|
||||
5. 学会枚举法的代码实现,能够将枚举思想转化为程序代码
|
||||
俊宇本节课表现很好!本节课的难度较上节课有所放缓,俊宇学习也变得更加自信,能够自己尝试着把这些代码通过自己的理解表达出来,这点进步非常大,老师为你感到高兴!
|
||||
你的数学基础很好,逻辑思维能力很强,这对学习编程是非常大的优势。希望你继续保持这种积极的学习状态,课后多花点时间动手练习,把理解的思路转化为实际的代码,慢慢提升代码实现能力。只要坚持练习,你的编程能力一定会越来越强的!
|
||||
加油呀!💪✨
|
||||
---
|
||||
@@ -8,3 +8,4 @@
|
||||
| 2026-03-29 | 连续性元素处理 | 第5课 | ⏸ 请假 | |
|
||||
| 2026-04-05 | 字符数组 | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-18 | 字符串处理 | 第7课 | ⏸ 请假 | 请假 |
|
||||
| 2026-05-01 | 枚举算法 | 第9课 | ✅ 出勤 | |
|
||||
|
||||
@@ -1,66 +1,50 @@
|
||||
# 郑子煜 课评汇总(2026春季)
|
||||
|
||||
**班级**:周六下午1400CSP03班
|
||||
**学生**:郑子煜
|
||||
|
||||
---
|
||||
|
||||
## 第1条:一二级知识回顾
|
||||
|
||||
**授课日期**:2026-03-08
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,我们本周复习的主题是《一二级知识回顾》
|
||||
|
||||
1. 复习数据类型
|
||||
2. 复习循环结构
|
||||
|
||||
**课堂反馈**:
|
||||
|
||||
(第1节课暂无具体评语)
|
||||
|
||||
---
|
||||
|
||||
## 第2条:数组计数
|
||||
|
||||
**授课日期**:2026-03-28
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《数组计数》:
|
||||
1. 数组的定义与初始化
|
||||
2. 数组遍历方法
|
||||
3. 计数器原理
|
||||
4. 数组下标运用
|
||||
5. 算法思维培养
|
||||
|
||||
子煜这节课能跟上节奏,但老师发现很多知识点可能还不太记得,有时候会不知道自己在做什么,脑子容易乱。希望子煜回去好好复习一下以前的知识点,把基础打扎实,上课才能更清楚自己在做什么~
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第3条:字符数组
|
||||
|
||||
**授课日期**:2026-04-05
|
||||
|
||||
**课评内容**:
|
||||
|
||||
子煜上课认真,能够跟上老师的节奏,对本周字符数组的知识点有一定掌握~课堂表现积极,状态在线!
|
||||
|
||||
希望子煜回去之后认真完成作业,多多练习巩固所学知识。理解字符数组的使用原理,不只是听懂就好~持续练习才能让知识更加牢固,编程能力更上一层楼。
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第7条:字符串处理
|
||||
|
||||
**授课日期**:2026-04-18
|
||||
|
||||
**课评内容**:
|
||||
|
||||
郑子煜本周请假,未上课。请子煜家长安排好时间,督促子煜在家复习本周字符串相关知识点,包括getline()、substr()、size()、find()函数的用法,并及时补做课后练习。如有疑问,欢迎随时联系老师。
|
||||
|
||||
---
|
||||
## 第8条:枚举算法
|
||||
**授课日期**:2026-05-01
|
||||
**课评内容**:
|
||||
家长好,本周学习的内容是《枚举算法》:
|
||||
1. 掌握使用自然语言、流程图、伪代码描述算法的方法
|
||||
2. 理解枚举法的概念与思想,掌握枚举法的基本实现方式
|
||||
3. 学会枚举法的边界确定,能够合理设置枚举范围
|
||||
4. 掌握枚举法的优化策略,能够减少不必要的枚举
|
||||
5. 学会枚举法的代码实现,能够将枚举思想转化为程序代码
|
||||
子煜本节课上课很积极,能够一直跟着老师进行互动,答题正确率很高!对质数、因数这些数学概念了解得很清楚,能够将相关思路转换成代码编写出来,状态非常棒,进步很明显。
|
||||
希望子煜回去之后继续巩固本节课的枚举算法知识点,多做相关练习,把基础打扎实,遇到不懂的地方及时和老师沟通。继续保持这种积极的学习状态,相信你会越来越棒的!
|
||||
加油呀!💪✨
|
||||
---
|
||||
@@ -8,3 +8,5 @@
|
||||
| 2026-03-29 | 连续性元素处理 | 第5课 | ⏸ 请假 | |
|
||||
| 2026-04-05 | 字符数组 | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-18 | 字符串处理 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-04-25 | 字符串小测与复习 | 第8课 | ✅ 出勤 | |
|
||||
| 2026-05-01 | 枚举算法 | 第9课 | ✅ 出勤 | |
|
||||
|
||||
@@ -1,94 +1,69 @@
|
||||
# 魏铭轩 课评汇总(2026春季)
|
||||
|
||||
**班级**:周六下午1400CSP03班
|
||||
**学生**:魏铭轩
|
||||
|
||||
---
|
||||
|
||||
## 第1条:一二级知识回顾
|
||||
|
||||
**授课日期**:2026-03-08
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,我们本周复习的主题是《一二级知识回顾》
|
||||
|
||||
1. 复习数据类型
|
||||
2. 复习循环结构
|
||||
|
||||
**课堂反馈**:
|
||||
|
||||
铭轩第一节课能跟上节奏积极互动,但下课后容易分心,老师关游戏还会赌气~希望铭轩能调整状态,把专注延续到整节课!💪🌈
|
||||
|
||||
---
|
||||
|
||||
## 第2条:数组计数
|
||||
|
||||
**授课日期**:2026-03-28
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《数组计数》:
|
||||
1. 数组的定义与初始化
|
||||
2. 数组遍历方法
|
||||
3. 计数器原理
|
||||
4. 数组下标运用
|
||||
5. 算法思维培养
|
||||
|
||||
铭轩这节课表现很棒!看得出来上个星期是有好好完成作业的,对知识点掌握的还不错。这个星期也比较认真,偷偷玩游戏的次数明显减少了,值得表扬!希望铭轩继续保持这种好状态,越来越棒~
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第3条:字符数组
|
||||
|
||||
**授课日期**:2026-04-05
|
||||
|
||||
**课评内容**:
|
||||
|
||||
铭轩状态在线,表现积极!能够跟着老师的节奏上课,对本节课字符数组的知识点掌握不错,老师看到了你的进步~
|
||||
|
||||
不过编程是需要持续练习的,为了防止遗忘,希望铭轩回去之后一定要多多练习。理解字符数组的使用原理,不只是完成作业就好~期待看到铭轩把所学知识转化为熟练的编程能力,加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第7条:字符串处理
|
||||
|
||||
**授课日期**:2026-04-18
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《字符串处理》:
|
||||
1. 学习getline()函数的使用,掌握读取一整行字符串的方法
|
||||
2. 学习substr()函数,理解字符串截取的方法和参数含义
|
||||
3. 学习size() / length()函数,掌握获取字符串长度的方法
|
||||
4. 学习find()函数,理解字符串查找的原理和返回值
|
||||
5. 培养学生对字符串处理的综合应用能力和编程思维
|
||||
|
||||
魏铭轩状态在线,表现积极,对本周字符串知识掌握很棒,课堂分神次数明显下降,是一个很大的进步,上课特别积极!希望铭轩继续保持,好记性不如烂笔头,一定要多多练习,熟能生巧,把掌握的知识巩固得更扎实。
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第8条:字符串小测与复习
|
||||
|
||||
**授课日期**:2026-04-25
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周我们进行了字符串知识点的小测与复习,主要内容包括:
|
||||
1. 字符串的声明方法
|
||||
2. 字符串长度获取与输入输出
|
||||
3. substr()截取函数和find()查找函数的使用
|
||||
4. 字符串函数的综合运用
|
||||
5. 课后复习习惯的培养
|
||||
|
||||
从课堂小测结果来看,铭轩能够掌握字符串的声明、长度获取和读取等基础知识点,这部分做得不错!但是对于substr()截取函数、find()查找函数这些稍微复杂一点的函数记得还不够牢固,需要回去认真复习。
|
||||
|
||||
老师看到铭轩这学期进步非常大,上课分神的次数明显减少,学习积极性也很高,这点特别值得表扬!以你的聪明程度,只要回去把笔记认真看一看、抄一抄,多花点时间复习,这些函数很快就能记牢。记得"好记性不如烂笔头",多练习才能把知识掌握得更扎实!
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
## 第9条:枚举算法
|
||||
**授课日期**:2026-05-01
|
||||
**课评内容**:
|
||||
家长好,本周学习的内容是《枚举算法》:
|
||||
1. 掌握使用自然语言、流程图、伪代码描述算法的方法
|
||||
2. 理解枚举法的概念与思想,掌握枚举法的基本实现方式
|
||||
3. 学会枚举法的边界确定,能够合理设置枚举范围
|
||||
4. 掌握枚举法的优化策略,能够减少不必要的枚举
|
||||
5. 学会枚举法的代码实现,能够将枚举思想转化为程序代码
|
||||
铭轩本节课的状态越来越好!能够服从老师的安排,紧跟着老师的节奏完成所有题目,学习积极性很高,老师看到了你的持续进步,非常欣慰!
|
||||
以你的聪明程度,只要继续保持这种认真的学习状态,课后多花点时间复习巩固本节课的枚举算法知识点,多做练习,一定能把这些知识掌握得很扎实。遇到问题的时候可以多尝试独立调试,慢慢提升自己解决问题的能力,你会越来越优秀的!
|
||||
加油呀!💪✨
|
||||
---
|
||||
@@ -91,3 +91,22 @@
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第6条:枚举算法
|
||||
|
||||
**授课日期**:2026-05-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《枚举算法》:
|
||||
1. 掌握使用自然语言、流程图、伪代码描述算法的方法
|
||||
2. 理解枚举法的概念与思想,掌握枚举法的基本实现方式
|
||||
3. 学会枚举法的边界确定,能够合理设置枚举范围
|
||||
4. 掌握枚举法的优化策略,能够减少不必要的枚举
|
||||
5. 学会枚举法的代码实现,能够将枚举思想转化为程序代码
|
||||
|
||||
华琛本节课整体状态不错,对老师讲的枚举算法知识点能够做出有效的答复,学习能力一直在线~不过从复习测试中发现,华琛对上周的string知识点有些遗忘,说明课后复习还需要加强哦。本阶段的知识点会越来越多,一定要养成及时复习的好习惯,每天花10分钟回顾一下学过的内容,把基础打扎实,后续学习会更轻松。
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
@@ -84,3 +84,22 @@
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第6条:枚举算法
|
||||
|
||||
**授课日期**:2026-05-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《枚举算法》:
|
||||
1. 掌握使用自然语言、流程图、伪代码描述算法的方法
|
||||
2. 理解枚举法的概念与思想,掌握枚举法的基本实现方式
|
||||
3. 学会枚举法的边界确定,能够合理设置枚举范围
|
||||
4. 掌握枚举法的优化策略,能够减少不必要的枚举
|
||||
5. 学会枚举法的代码实现,能够将枚举思想转化为程序代码
|
||||
|
||||
钎宸本节课表现不错,能够完成较多的题目,做题速度相比之前有所提升,这是很大的进步~不过老师发现钎宸在课堂上偶尔会开小差,注意力不够集中,如果能够把专注力再提升一些,跟着老师的节奏走,学习效果一定会更好。建议在家可以每天练习静坐10分钟,慢慢培养专注力,相信你会越来越棒的!
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
@@ -84,3 +84,22 @@
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第9条:枚举算法
|
||||
|
||||
**授课日期**:2026-05-04
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《枚举算法》:
|
||||
1. 掌握使用自然语言、流程图、伪代码描述算法的方法
|
||||
2. 理解枚举法的概念与思想,掌握枚举法的基本实现方式
|
||||
3. 学会枚举法的边界确定,能够合理设置枚举范围
|
||||
4. 掌握枚举法的优化策略,能够减少不必要的枚举
|
||||
5. 学会枚举法的代码实现,能够将枚举思想转化为程序代码
|
||||
|
||||
佳琳本节课完成了大部分的题目,课堂状态整体不错,对枚举知识能够掌握,这种认真的学习态度值得肯定!枚举算法需要理清思路,一步步去尝试,佳琳的专注力是很适合学习这类算法的。希望佳琳在做题时不要怕出错,先把想到的思路写出来,遇到问题再慢慢调整,相信以你的认真劲儿一定能越做越好!
|
||||
|
||||
加油呀!💪✨
|
||||
|
||||
---
|
||||
|
||||
@@ -9,3 +9,4 @@
|
||||
| 2026-04-05 | 四季之选 | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-17 | 彩虹生成器 | 第8课 | ✅ 出勤 | |
|
||||
| 2026-04-11 | 我的唱片机 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-05-01 | 唐诗朗诵会 | 第9课 | ✅ 出勤 | |
|
||||
|
||||
@@ -148,3 +148,24 @@
|
||||
继续加油哦!期待看到你更完美的表现!💪✨
|
||||
|
||||
---
|
||||
|
||||
## 第9条:唐诗朗诵会
|
||||
|
||||
**授课日期**:2026-05-01
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《唐诗朗诵会》:
|
||||
1. 复习循环嵌套结构,应用循环嵌套结构实现诗词的展示效果
|
||||
2. 能够朗诵诗词并录制声音
|
||||
3. 通过唐诗朗诵会项目的制作,探究循环嵌套结构的综合应用
|
||||
4. 欣赏古诗词,感受古诗词的魅力,并通过诗词朗诵陶冶性情,开阔胸怀
|
||||
5. 培养学生的逻辑思维能力和创意表达能力
|
||||
|
||||
煜腾上课很活跃,对学习的循环嵌套结构能够理解,特别是能够知道外层循环是做什么工作,内层循环是做什么工作,头脑聪明,反应又快!在制作《唐诗朗诵会》项目时,煜腾能够主动完成任务,表现出很强的学习能力。
|
||||
|
||||
做任务的时候会有一点点浮躁,不过老师相信煜腾只要把聪明和耐心结合起来,一定能做出更精致的作品~真正的高手不仅求快,更求好!
|
||||
|
||||
继续加油哦!期待看到你更完美的表现!💪✨
|
||||
|
||||
---
|
||||
|
||||
@@ -9,3 +9,4 @@
|
||||
| 2026-04-05 | 四季之选 | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-17 | 彩虹生成器 | 第8课 | ✅ 出勤 | |
|
||||
| 2026-04-11 | 我的唱片机 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-05-01 | 唐诗朗诵会 | 第9课 | ✅ 出勤 | |
|
||||
|
||||
@@ -156,3 +156,24 @@
|
||||
继续加油哦!老师很期待看到你下一个有创意的作品!🌟😊
|
||||
|
||||
---
|
||||
|
||||
## 第9条:唐诗朗诵会
|
||||
|
||||
**授课日期**:2026-05-01
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《唐诗朗诵会》:
|
||||
1. 复习循环嵌套结构,应用循环嵌套结构实现诗词的展示效果
|
||||
2. 能够朗诵诗词并录制声音
|
||||
3. 通过唐诗朗诵会项目的制作,探究循环嵌套结构的综合应用
|
||||
4. 欣赏古诗词,感受古诗词的魅力,并通过诗词朗诵陶冶性情,开阔胸怀
|
||||
5. 培养学生的逻辑思维能力和创意表达能力
|
||||
|
||||
晨语做完自己的任务后,可能觉得项目会有一点枯燥,不太愿意继续动手。不过在老师安抚情绪之后,能够静下心来,一点一点地把作品完成,到了回答问题的时候,晨语也可以认真把问题回答出来,这一点很棒!
|
||||
|
||||
晨语一直都很有创意,想法天马行空,这是非常宝贵的特质~目前对外层循环和内层循环的区别还有一点点没弄清,后续老师会继续加强循环结构的讲解。要是能更专注一些,把循环结构理解得更透彻,一定会做出更有创意的作品!
|
||||
|
||||
继续加油哦!老师很期待看到你下一个有创意的作品!🌟😊
|
||||
|
||||
---
|
||||
|
||||
@@ -9,3 +9,4 @@
|
||||
| 2026-04-05 | 四季之选 | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-17 | 彩虹生成器 | 第8课 | ✅ 出勤 | |
|
||||
| 2026-04-11 | 我的唱片机 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-05-01 | 唐诗朗诵会 | 第9课 | ✅ 出勤 | |
|
||||
|
||||
@@ -160,3 +160,24 @@
|
||||
继续加油哦!期待看到你更棒的表现!🌟💪
|
||||
|
||||
---
|
||||
|
||||
## 第9条:唐诗朗诵会
|
||||
|
||||
**授课日期**:2026-05-01
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《唐诗朗诵会》:
|
||||
1. 复习循环嵌套结构,应用循环嵌套结构实现诗词的展示效果
|
||||
2. 能够朗诵诗词并录制声音
|
||||
3. 通过唐诗朗诵会项目的制作,探究循环嵌套结构的综合应用
|
||||
4. 欣赏古诗词,感受古诗词的魅力,并通过诗词朗诵陶冶性情,开阔胸怀
|
||||
5. 培养学生的逻辑思维能力和创意表达能力
|
||||
|
||||
艺嘉对本阶段学习的循环嵌套功能掌握得很扎实,能够很清楚地认识到外层循环是做什么工作,内层循环是做什么工作,整节课的逻辑分析都很清楚!在制作《唐诗朗诵会》项目时,艺嘉能够把循环嵌套的结构运用到诗词展示效果中,思路非常清晰。
|
||||
|
||||
艺嘉上课时遇到自己懂的内容,总是敢于大声表达,特别有自信~这种积极的课堂表现非常棒!
|
||||
|
||||
继续加油哦!老师会继续关注艺嘉的表现,期待看到你更棒的作品!🌟💪
|
||||
|
||||
---
|
||||
|
||||
@@ -9,3 +9,4 @@
|
||||
| 2026-04-05 | 四季之选 | 第6课 | ✅ 出勤 | |
|
||||
| 2026-04-17 | 彩虹生成器 | 第8课 | ✅ 出勤 | |
|
||||
| 2026-04-11 | 我的唱片机 | 第7课 | ✅ 出勤 | |
|
||||
| 2026-05-01 | 唐诗朗诵会 | 第9课 | ✅ 出勤 | |
|
||||
|
||||
@@ -154,3 +154,24 @@
|
||||
继续加油哦!相信你会把程序做得更完整!🌟💡
|
||||
|
||||
---
|
||||
|
||||
## 第9条:唐诗朗诵会
|
||||
|
||||
**授课日期**:2026-05-01
|
||||
|
||||
**课评内容**:
|
||||
|
||||
家长好,本周学习的内容是《唐诗朗诵会》:
|
||||
1. 复习循环嵌套结构,应用循环嵌套结构实现诗词的展示效果
|
||||
2. 能够朗诵诗词并录制声音
|
||||
3. 通过唐诗朗诵会项目的制作,探究循环嵌套结构的综合应用
|
||||
4. 欣赏古诗词,感受古诗词的魅力,并通过诗词朗诵陶冶性情,开阔胸怀
|
||||
5. 培养学生的逻辑思维能力和创意表达能力
|
||||
|
||||
圆振可以确保自己的项目能够完成,对本节课学习的循环嵌套有所了解,能够认识到外层循环是做什么工作,内层循环是做什么工作。圆振认真完成了《唐诗朗诵会》的作品,能够把诗词展示效果做出来,特别棒!
|
||||
|
||||
作为班里年龄较小的同学,圆振的理解力和反应速度一直都很出色~不过老师发现圆振偶尔会有一点发呆,专注力可以再提升一些。如果能更集中注意力听课,作品一定会做得更完整!
|
||||
|
||||
继续加油哦!相信你会把程序做得更完整!
|
||||
|
||||
---
|
||||
|
||||
@@ -42,7 +42,11 @@
|
||||
"Bash(start:*)",
|
||||
"Bash(start \"\" \".claude-design\\\\slide-previews\\\\style-c.html\")",
|
||||
"Bash(findstr:*)",
|
||||
"Bash(tree:*)"
|
||||
"Bash(tree:*)",
|
||||
"Bash(curl *)",
|
||||
"Bash(python *)",
|
||||
"Bash(node index.js 2026-04-24 2026-04-26)",
|
||||
"Bash(node *)"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
145
.claude/skills/教学日程查询/README.md
Normal file
145
.claude/skills/教学日程查询/README.md
Normal file
@@ -0,0 +1,145 @@
|
||||
# 教学日程查询 Skill 使用说明
|
||||
|
||||
## 功能概述
|
||||
本技能**直接调用公司API获取实时教学排课数据**,支持查询指定日期或时间段的课程安排,自动生成功能完整的互动网页,帮助老师快速查询授课安排,查看学生名单和出勤情况,支持单天查询和任意时间段查询两种模式。
|
||||
|
||||
## 环境配置
|
||||
### 1. 依赖安装
|
||||
首次使用前需要安装技能依赖:
|
||||
```bash
|
||||
cd .claude/skills/教学日程查询
|
||||
npm install
|
||||
```
|
||||
|
||||
### 2. API配置
|
||||
确保项目根目录下的 `.env` 文件包含正确的API配置:
|
||||
```env
|
||||
# 公司API地址
|
||||
API_BASE_URL=https://api.qonnwolf.com/api/v1
|
||||
# API认证令牌
|
||||
AUTHORIZATION=Bearer your_token_here
|
||||
# 默认查询的老师姓名
|
||||
EMPLOYEE_NAME=橙子(程城)
|
||||
```
|
||||
|
||||
## 快速开始
|
||||
### 1. 调用技能
|
||||
在Claude Code对话中输入,支持多种日期格式:
|
||||
```
|
||||
# 方式1:查询单天
|
||||
/教学日程查询 # 查询当天日程
|
||||
/教学日程查询 2026-04-28 # 标准格式
|
||||
/教学日程查询 2026/04/28 # 斜杠格式
|
||||
/教学日程查询 20260428 # 纯数字格式
|
||||
/教学日程查询 4月28日 # 中文格式
|
||||
/教学日程查询 04-28 # 短格式(默认当前年份)
|
||||
|
||||
# 方式2:查询时间段
|
||||
/教学日程查询 2026-04-01 2026-04-30 # 查询4月整个月的日程
|
||||
/教学日程查询 4月24日 4月26日 # 中文格式时间段
|
||||
/教学日程查询 20260422 20260428 # 纯数字格式时间段
|
||||
```
|
||||
|
||||
### 2. 查看结果
|
||||
技能执行完成后会返回网页链接,点击链接即可打开互动网页查看详细信息。
|
||||
|
||||
## 网页功能说明
|
||||
### 顶部功能区
|
||||
- **日期范围显示**:显示当前查询的日期范围和总天数
|
||||
- **搜索框**:输入日期、班级名称或学生姓名进行全局快速搜索
|
||||
- **导出按钮**:点击导出整个时间段的课表为Excel文件
|
||||
- **视图切换**:支持「按日期」和「按班级」两种视图模式一键切换
|
||||
|
||||
### 统计面板
|
||||
- 展示查询范围内的总天数、总课程数、总学生人次
|
||||
- 汇总出勤人次、缺勤人次,直观展示整体出勤情况
|
||||
|
||||
### 课表展示区
|
||||
#### 按日期视图(默认)
|
||||
- 按日期分组展示,每天的课程独立排列
|
||||
- 日期头部粘性定位,滚动时始终可见
|
||||
- 每个日期组显示当日的课程数量、学生人次和出勤统计
|
||||
- 课程按时间顺序排列,每个课程以卡片形式展示
|
||||
- 卡片显示:班级名称、授课时间、授课老师、学生人数、出勤统计
|
||||
- 点击卡片展开查看该班级的详细学生名单
|
||||
|
||||
#### 按班级视图
|
||||
- 按班级分组展示,同一个班级的所有课程集中排列
|
||||
- 每个班级组显示课程次数和时间范围
|
||||
- 方便查看同一个班级在整个时间段内的所有上课情况
|
||||
|
||||
### 学生名单
|
||||
- 表格展示学生姓名和出勤状态
|
||||
- 出勤状态标识:
|
||||
- ✅ 出勤:正常上课
|
||||
- ⏸ 请假:已请假
|
||||
- ❌ 缺勤:未上课
|
||||
- 支持按出勤状态筛选学生
|
||||
|
||||
### 导出功能
|
||||
导出的Excel文件包含以下信息:
|
||||
- 课程日期
|
||||
- 班级名称
|
||||
- 授课时间
|
||||
- 授课老师
|
||||
- 教室
|
||||
- 学生姓名
|
||||
- 出勤状态
|
||||
- 备注信息
|
||||
* 时间段查询会导出所有日期的完整数据,自动按日期排序
|
||||
|
||||
## 目录结构
|
||||
```
|
||||
教学日程查询/
|
||||
├── index.js # 主程序文件,处理API调用和网页生成
|
||||
├── package.json # 依赖配置文件
|
||||
├── skill.md # Claude技能定义文件
|
||||
├── template.html # 网页模板文件
|
||||
└── README.md # 使用说明文档
|
||||
```
|
||||
|
||||
## 输出目录
|
||||
生成的文件保存在:
|
||||
```
|
||||
# 单天查询
|
||||
.claude/output/teaching-schedule/2026-04-28/
|
||||
├── schedule.html # 互动网页
|
||||
└── schedule.json # 原始API数据
|
||||
|
||||
# 时间段查询
|
||||
.claude/output/teaching-schedule/2026-04-01_2026-04-30/
|
||||
├── schedule.html # 互动网页
|
||||
└── schedule.json # 原始API数据(包含多天的完整数据)
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
### Q: API调用失败提示认证失败?
|
||||
A: 请检查项目根目录下 `.env` 文件中的 `AUTHORIZATION` 配置是否正确,令牌是否过期。
|
||||
|
||||
### Q: API调用失败提示网络错误?
|
||||
A: 请检查网络连接是否正常,是否能够访问公司API地址,或者稍后重试。如果问题持续存在,请联系技术支持。
|
||||
|
||||
### Q: 为什么没有数据?
|
||||
A: 可能是查询的日期没有排课,或者API返回数据为空。可以尝试查询其他日期,或者检查 `EMPLOYEE_NAME` 配置是否正确。
|
||||
|
||||
### Q: 导出的Excel文件打不开?
|
||||
A: 请确保使用支持.xlsx格式的办公软件打开,如Microsoft Excel、WPS等。
|
||||
|
||||
### Q: 可以查询其他老师的课表吗?
|
||||
A: 可以修改 `.env` 文件中的 `EMPLOYEE_NAME` 配置为要查询的老师姓名,支持模糊匹配。
|
||||
|
||||
## 更新日志
|
||||
### v1.1.0 (2026-04-28)
|
||||
- ✨ 新增时间段查询功能,支持查询任意起止日期范围内的所有日程
|
||||
- ✨ 新增双视图展示模式:按日期视图、按班级视图,一键切换
|
||||
- ✨ 升级统计面板,展示总天数、总课程数、总学生人次等汇总信息
|
||||
- ✨ 搜索功能升级,支持按日期、班级、学生姓名全局搜索
|
||||
- ✨ 导出功能升级,支持导出整个时间段的完整数据
|
||||
- ✨ 优化界面设计,日期分组头部支持粘性定位,滚动浏览更方便
|
||||
- ♻️ 重构数据处理逻辑,支持多天数据的合并和展示
|
||||
|
||||
### v1.0.0 (2026-04-28)
|
||||
- 初始版本发布
|
||||
- 支持基础的单天日程查询功能
|
||||
- 支持搜索、筛选、导出Excel功能
|
||||
- 响应式界面设计
|
||||
222
.claude/skills/教学日程查询/index.js
Normal file
222
.claude/skills/教学日程查询/index.js
Normal file
@@ -0,0 +1,222 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const axios = require('axios');
|
||||
require('dotenv').config({ path: path.join(__dirname, '../../../.env') });
|
||||
|
||||
// API配置
|
||||
const API_BASE_URL = process.env.API_BASE_URL || 'https://api.qonnwolf.com/api/v1';
|
||||
const AUTHORIZATION = process.env.AUTHORIZATION || '';
|
||||
const TEACHER_NAME = process.env.EMPLOYEE_NAME || '橙子(程城)';
|
||||
|
||||
// 日期处理工具函数
|
||||
function formatDate(date) {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
function parseDate(dateStr) {
|
||||
// 支持多种日期格式:2026-04-24、2026/04/24、20260424、04-24、4月24日等
|
||||
dateStr = dateStr.replace(/年|月/g, '-').replace(/日/g, '');
|
||||
|
||||
// 如果是短日期,默认使用当前年份
|
||||
if (/^\d{1,2}-\d{1,2}$/.test(dateStr)) {
|
||||
const currentYear = new Date().getFullYear();
|
||||
dateStr = `${currentYear}-${dateStr}`;
|
||||
}
|
||||
|
||||
// 处理纯数字格式
|
||||
if (/^\d{8}$/.test(dateStr)) {
|
||||
dateStr = `${dateStr.slice(0, 4)}-${dateStr.slice(4, 6)}-${dateStr.slice(6, 8)}`;
|
||||
}
|
||||
|
||||
// 替换斜杠为横杠
|
||||
dateStr = dateStr.replace(/\//g, '-');
|
||||
|
||||
const date = new Date(dateStr);
|
||||
if (isNaN(date.getTime())) {
|
||||
throw new Error(`无效的日期格式:${dateStr},请使用YYYY-MM-DD格式`);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
function getDateRange(startDateStr, endDateStr) {
|
||||
const startDate = parseDate(startDateStr);
|
||||
const endDate = endDateStr ? parseDate(endDateStr) : startDate;
|
||||
|
||||
if (startDate > endDate) {
|
||||
throw new Error('开始日期不能晚于结束日期');
|
||||
}
|
||||
|
||||
const dates = [];
|
||||
const currentDate = new Date(startDate);
|
||||
while (currentDate <= endDate) {
|
||||
dates.push(formatDate(currentDate));
|
||||
currentDate.setDate(currentDate.getDate() + 1);
|
||||
}
|
||||
return dates;
|
||||
}
|
||||
|
||||
// 调用API获取单天数据
|
||||
async function fetchSchedule(date) {
|
||||
try {
|
||||
console.log(`正在获取 ${date} 的教学日程数据...`);
|
||||
const response = await axios.get(`${API_BASE_URL}/reports/teaching-schedule`, {
|
||||
headers: {
|
||||
'Authorization': AUTHORIZATION
|
||||
},
|
||||
params: {
|
||||
teaching_date: date,
|
||||
teacher_name: TEACHER_NAME
|
||||
}
|
||||
});
|
||||
|
||||
if (response.data.code !== 0) {
|
||||
throw new Error(`API返回错误:${response.data.message}`);
|
||||
}
|
||||
|
||||
const data = response.data.data;
|
||||
return {
|
||||
teaching_date: date,
|
||||
items: data.items.map(item => ({
|
||||
class_id: item.class_id,
|
||||
class_name: item.class_name,
|
||||
start_time: item.teaching_time_period.split('-')[0].trim(),
|
||||
end_time: item.teaching_time_period.split('-')[1].trim(),
|
||||
teacher_name: item.teacher_name,
|
||||
classroom: item.school_name,
|
||||
students: item.student_names.map(name => {
|
||||
// 先默认都是出勤,后续可以根据实际出勤数据调整
|
||||
return {
|
||||
student_name: name,
|
||||
attendance_status: '✅ 出勤',
|
||||
remark: ''
|
||||
};
|
||||
})
|
||||
}))
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`获取 ${date} 数据失败:`, error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 批量获取日期范围内的数据
|
||||
async function fetchScheduleRange(dates) {
|
||||
const scheduleData = [];
|
||||
for (const date of dates) {
|
||||
const data = await fetchSchedule(date);
|
||||
scheduleData.push(data);
|
||||
}
|
||||
return scheduleData;
|
||||
}
|
||||
|
||||
// 生成HTML文件
|
||||
function generateHTML(scheduleData, startDate, endDate) {
|
||||
// 读取模板文件
|
||||
const templatePath = path.join(__dirname, 'template.html');
|
||||
let template = fs.readFileSync(templatePath, 'utf-8');
|
||||
|
||||
// 生成日期范围显示文本
|
||||
const dateRangeText = startDate === endDate ? startDate : `${startDate} 至 ${endDate}`;
|
||||
const updateTime = formatDate(new Date()) + ' ' + new Date().toTimeString().slice(0, 5);
|
||||
|
||||
// 替换模板中的占位符
|
||||
template = template.replace(/{{dateRange}}/g, dateRangeText);
|
||||
template = template.replace(/{{updateTime}}/g, updateTime);
|
||||
template = template.replace(/{{totalDays}}/g, scheduleData.length);
|
||||
template = template.replace(/const scheduleData = {{scheduleData}};/, `const scheduleData = ${JSON.stringify(scheduleData, null, 2)};`);
|
||||
|
||||
// 确保输出目录存在
|
||||
const outputDir = path.join(__dirname, `../../../output/teaching-schedule/${dateRangeText.replace(/ 至 /g, '_')}`);
|
||||
if (!fs.existsSync(outputDir)) {
|
||||
fs.mkdirSync(outputDir, { recursive: true });
|
||||
}
|
||||
|
||||
// 写入HTML文件
|
||||
const htmlPath = path.join(outputDir, 'schedule.html');
|
||||
fs.writeFileSync(htmlPath, template, 'utf-8');
|
||||
|
||||
// 写入JSON数据文件
|
||||
const jsonPath = path.join(outputDir, 'schedule.json');
|
||||
fs.writeFileSync(jsonPath, JSON.stringify(scheduleData, null, 2), 'utf-8');
|
||||
|
||||
return {
|
||||
htmlPath,
|
||||
jsonPath,
|
||||
outputDir,
|
||||
dateRangeText
|
||||
};
|
||||
}
|
||||
|
||||
// 主函数
|
||||
async function main() {
|
||||
try {
|
||||
// 解析命令行参数
|
||||
const args = process.argv.slice(2);
|
||||
let startDateStr, endDateStr;
|
||||
|
||||
if (args.length === 0) {
|
||||
// 默认查询今天
|
||||
const today = new Date();
|
||||
startDateStr = formatDate(today);
|
||||
endDateStr = startDateStr;
|
||||
} else if (args.length === 1) {
|
||||
// 查询单天
|
||||
startDateStr = args[0];
|
||||
endDateStr = startDateStr;
|
||||
} else {
|
||||
// 查询时间段
|
||||
startDateStr = args[0];
|
||||
endDateStr = args[1];
|
||||
}
|
||||
|
||||
// 获取日期范围
|
||||
const dates = getDateRange(startDateStr, endDateStr);
|
||||
const startDate = dates[0];
|
||||
const endDate = dates[dates.length - 1];
|
||||
|
||||
console.log(`查询日期范围:${startDate} 至 ${endDate}`);
|
||||
console.log(`共 ${dates.length} 天`);
|
||||
|
||||
// 获取数据
|
||||
const scheduleData = await fetchScheduleRange(dates);
|
||||
|
||||
// 统计信息
|
||||
const totalClasses = scheduleData.reduce((sum, day) => sum + day.items.length, 0);
|
||||
const totalStudents = scheduleData.reduce((sum, day) => {
|
||||
return sum + day.items.reduce((daySum, cls) => daySum + cls.students.length, 0);
|
||||
}, 0);
|
||||
|
||||
console.log(`查询完成:共 ${totalClasses} 节课,${totalStudents} 人次`);
|
||||
|
||||
// 生成HTML
|
||||
const result = generateHTML(scheduleData, startDate, endDate);
|
||||
|
||||
console.log('');
|
||||
console.log('✅ 教学日程生成成功!');
|
||||
console.log('📁 输出目录:', result.outputDir);
|
||||
console.log('📄 网页文件:', result.htmlPath);
|
||||
console.log('📊 数据文件:', result.jsonPath);
|
||||
console.log('');
|
||||
console.log('直接打开schedule.html文件即可查看教学日程!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 生成失败:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// 运行主函数
|
||||
if (require.main === module) {
|
||||
main();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
fetchSchedule,
|
||||
fetchScheduleRange,
|
||||
generateHTML
|
||||
};
|
||||
302
.claude/skills/教学日程查询/node_modules/.package-lock.json
generated
vendored
Normal file
302
.claude/skills/教学日程查询/node_modules/.package-lock.json
generated
vendored
Normal file
@@ -0,0 +1,302 @@
|
||||
{
|
||||
"name": "teaching-schedule-query",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.15.2.tgz",
|
||||
"integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.11",
|
||||
"form-data": "^4.0.5",
|
||||
"proxy-from-env": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind-apply-helpers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv": {
|
||||
"version": "16.6.1",
|
||||
"resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.6.1.tgz",
|
||||
"integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://dotenvx.com"
|
||||
}
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-errors": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-object-atoms": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-set-tostringtag": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
||||
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.6",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"hasown": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.16.0.tgz",
|
||||
"integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.5.tgz",
|
||||
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
"es-define-property": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"es-object-atoms": "^1.1.1",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-proto": "^1.0.1",
|
||||
"gopd": "^1.2.0",
|
||||
"has-symbols": "^1.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"math-intrinsics": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dunder-proto": "^1.0.1",
|
||||
"es-object-atoms": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
|
||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-tostringtag": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.3.tgz",
|
||||
"integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-2.1.0.tgz",
|
||||
"integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
21
.claude/skills/教学日程查询/node_modules/asynckit/LICENSE
generated
vendored
Normal file
21
.claude/skills/教学日程查询/node_modules/asynckit/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Alex Indigo
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
233
.claude/skills/教学日程查询/node_modules/asynckit/README.md
generated
vendored
Normal file
233
.claude/skills/教学日程查询/node_modules/asynckit/README.md
generated
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
# asynckit [](https://www.npmjs.com/package/asynckit)
|
||||
|
||||
Minimal async jobs utility library, with streams support.
|
||||
|
||||
[](https://travis-ci.org/alexindigo/asynckit)
|
||||
[](https://travis-ci.org/alexindigo/asynckit)
|
||||
[](https://ci.appveyor.com/project/alexindigo/asynckit)
|
||||
|
||||
[](https://coveralls.io/github/alexindigo/asynckit?branch=master)
|
||||
[](https://david-dm.org/alexindigo/asynckit)
|
||||
[](https://www.bithound.io/github/alexindigo/asynckit)
|
||||
|
||||
<!-- [](https://www.npmjs.com/package/reamde) -->
|
||||
|
||||
AsyncKit provides harness for `parallel` and `serial` iterators over list of items represented by arrays or objects.
|
||||
Optionally it accepts abort function (should be synchronously return by iterator for each item), and terminates left over jobs upon an error event. For specific iteration order built-in (`ascending` and `descending`) and custom sort helpers also supported, via `asynckit.serialOrdered` method.
|
||||
|
||||
It ensures async operations to keep behavior more stable and prevent `Maximum call stack size exceeded` errors, from sync iterators.
|
||||
|
||||
| compression | size |
|
||||
| :----------------- | -------: |
|
||||
| asynckit.js | 12.34 kB |
|
||||
| asynckit.min.js | 4.11 kB |
|
||||
| asynckit.min.js.gz | 1.47 kB |
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
$ npm install --save asynckit
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Parallel Jobs
|
||||
|
||||
Runs iterator over provided array in parallel. Stores output in the `result` array,
|
||||
on the matching positions. In unlikely event of an error from one of the jobs,
|
||||
will terminate rest of the active jobs (if abort function is provided)
|
||||
and return error along with salvaged data to the main callback function.
|
||||
|
||||
#### Input Array
|
||||
|
||||
```javascript
|
||||
var parallel = require('asynckit').parallel
|
||||
, assert = require('assert')
|
||||
;
|
||||
|
||||
var source = [ 1, 1, 4, 16, 64, 32, 8, 2 ]
|
||||
, expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ]
|
||||
, expectedTarget = [ 1, 1, 2, 4, 8, 16, 32, 64 ]
|
||||
, target = []
|
||||
;
|
||||
|
||||
parallel(source, asyncJob, function(err, result)
|
||||
{
|
||||
assert.deepEqual(result, expectedResult);
|
||||
assert.deepEqual(target, expectedTarget);
|
||||
});
|
||||
|
||||
// async job accepts one element from the array
|
||||
// and a callback function
|
||||
function asyncJob(item, cb)
|
||||
{
|
||||
// different delays (in ms) per item
|
||||
var delay = item * 25;
|
||||
|
||||
// pretend different jobs take different time to finish
|
||||
// and not in consequential order
|
||||
var timeoutId = setTimeout(function() {
|
||||
target.push(item);
|
||||
cb(null, item * 2);
|
||||
}, delay);
|
||||
|
||||
// allow to cancel "leftover" jobs upon error
|
||||
// return function, invoking of which will abort this job
|
||||
return clearTimeout.bind(null, timeoutId);
|
||||
}
|
||||
```
|
||||
|
||||
More examples could be found in [test/test-parallel-array.js](test/test-parallel-array.js).
|
||||
|
||||
#### Input Object
|
||||
|
||||
Also it supports named jobs, listed via object.
|
||||
|
||||
```javascript
|
||||
var parallel = require('asynckit/parallel')
|
||||
, assert = require('assert')
|
||||
;
|
||||
|
||||
var source = { first: 1, one: 1, four: 4, sixteen: 16, sixtyFour: 64, thirtyTwo: 32, eight: 8, two: 2 }
|
||||
, expectedResult = { first: 2, one: 2, four: 8, sixteen: 32, sixtyFour: 128, thirtyTwo: 64, eight: 16, two: 4 }
|
||||
, expectedTarget = [ 1, 1, 2, 4, 8, 16, 32, 64 ]
|
||||
, expectedKeys = [ 'first', 'one', 'two', 'four', 'eight', 'sixteen', 'thirtyTwo', 'sixtyFour' ]
|
||||
, target = []
|
||||
, keys = []
|
||||
;
|
||||
|
||||
parallel(source, asyncJob, function(err, result)
|
||||
{
|
||||
assert.deepEqual(result, expectedResult);
|
||||
assert.deepEqual(target, expectedTarget);
|
||||
assert.deepEqual(keys, expectedKeys);
|
||||
});
|
||||
|
||||
// supports full value, key, callback (shortcut) interface
|
||||
function asyncJob(item, key, cb)
|
||||
{
|
||||
// different delays (in ms) per item
|
||||
var delay = item * 25;
|
||||
|
||||
// pretend different jobs take different time to finish
|
||||
// and not in consequential order
|
||||
var timeoutId = setTimeout(function() {
|
||||
keys.push(key);
|
||||
target.push(item);
|
||||
cb(null, item * 2);
|
||||
}, delay);
|
||||
|
||||
// allow to cancel "leftover" jobs upon error
|
||||
// return function, invoking of which will abort this job
|
||||
return clearTimeout.bind(null, timeoutId);
|
||||
}
|
||||
```
|
||||
|
||||
More examples could be found in [test/test-parallel-object.js](test/test-parallel-object.js).
|
||||
|
||||
### Serial Jobs
|
||||
|
||||
Runs iterator over provided array sequentially. Stores output in the `result` array,
|
||||
on the matching positions. In unlikely event of an error from one of the jobs,
|
||||
will not proceed to the rest of the items in the list
|
||||
and return error along with salvaged data to the main callback function.
|
||||
|
||||
#### Input Array
|
||||
|
||||
```javascript
|
||||
var serial = require('asynckit/serial')
|
||||
, assert = require('assert')
|
||||
;
|
||||
|
||||
var source = [ 1, 1, 4, 16, 64, 32, 8, 2 ]
|
||||
, expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ]
|
||||
, expectedTarget = [ 0, 1, 2, 3, 4, 5, 6, 7 ]
|
||||
, target = []
|
||||
;
|
||||
|
||||
serial(source, asyncJob, function(err, result)
|
||||
{
|
||||
assert.deepEqual(result, expectedResult);
|
||||
assert.deepEqual(target, expectedTarget);
|
||||
});
|
||||
|
||||
// extended interface (item, key, callback)
|
||||
// also supported for arrays
|
||||
function asyncJob(item, key, cb)
|
||||
{
|
||||
target.push(key);
|
||||
|
||||
// it will be automatically made async
|
||||
// even it iterator "returns" in the same event loop
|
||||
cb(null, item * 2);
|
||||
}
|
||||
```
|
||||
|
||||
More examples could be found in [test/test-serial-array.js](test/test-serial-array.js).
|
||||
|
||||
#### Input Object
|
||||
|
||||
Also it supports named jobs, listed via object.
|
||||
|
||||
```javascript
|
||||
var serial = require('asynckit').serial
|
||||
, assert = require('assert')
|
||||
;
|
||||
|
||||
var source = [ 1, 1, 4, 16, 64, 32, 8, 2 ]
|
||||
, expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ]
|
||||
, expectedTarget = [ 0, 1, 2, 3, 4, 5, 6, 7 ]
|
||||
, target = []
|
||||
;
|
||||
|
||||
var source = { first: 1, one: 1, four: 4, sixteen: 16, sixtyFour: 64, thirtyTwo: 32, eight: 8, two: 2 }
|
||||
, expectedResult = { first: 2, one: 2, four: 8, sixteen: 32, sixtyFour: 128, thirtyTwo: 64, eight: 16, two: 4 }
|
||||
, expectedTarget = [ 1, 1, 4, 16, 64, 32, 8, 2 ]
|
||||
, target = []
|
||||
;
|
||||
|
||||
|
||||
serial(source, asyncJob, function(err, result)
|
||||
{
|
||||
assert.deepEqual(result, expectedResult);
|
||||
assert.deepEqual(target, expectedTarget);
|
||||
});
|
||||
|
||||
// shortcut interface (item, callback)
|
||||
// works for object as well as for the arrays
|
||||
function asyncJob(item, cb)
|
||||
{
|
||||
target.push(item);
|
||||
|
||||
// it will be automatically made async
|
||||
// even it iterator "returns" in the same event loop
|
||||
cb(null, item * 2);
|
||||
}
|
||||
```
|
||||
|
||||
More examples could be found in [test/test-serial-object.js](test/test-serial-object.js).
|
||||
|
||||
_Note: Since _object_ is an _unordered_ collection of properties,
|
||||
it may produce unexpected results with sequential iterations.
|
||||
Whenever order of the jobs' execution is important please use `serialOrdered` method._
|
||||
|
||||
### Ordered Serial Iterations
|
||||
|
||||
TBD
|
||||
|
||||
For example [compare-property](compare-property) package.
|
||||
|
||||
### Streaming interface
|
||||
|
||||
TBD
|
||||
|
||||
## Want to Know More?
|
||||
|
||||
More examples can be found in [test folder](test/).
|
||||
|
||||
Or open an [issue](https://github.com/alexindigo/asynckit/issues) with questions and/or suggestions.
|
||||
|
||||
## License
|
||||
|
||||
AsyncKit is licensed under the MIT license.
|
||||
76
.claude/skills/教学日程查询/node_modules/asynckit/bench.js
generated
vendored
Normal file
76
.claude/skills/教学日程查询/node_modules/asynckit/bench.js
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/* eslint no-console: "off" */
|
||||
|
||||
var asynckit = require('./')
|
||||
, async = require('async')
|
||||
, assert = require('assert')
|
||||
, expected = 0
|
||||
;
|
||||
|
||||
var Benchmark = require('benchmark');
|
||||
var suite = new Benchmark.Suite;
|
||||
|
||||
var source = [];
|
||||
for (var z = 1; z < 100; z++)
|
||||
{
|
||||
source.push(z);
|
||||
expected += z;
|
||||
}
|
||||
|
||||
suite
|
||||
// add tests
|
||||
|
||||
.add('async.map', function(deferred)
|
||||
{
|
||||
var total = 0;
|
||||
|
||||
async.map(source,
|
||||
function(i, cb)
|
||||
{
|
||||
setImmediate(function()
|
||||
{
|
||||
total += i;
|
||||
cb(null, total);
|
||||
});
|
||||
},
|
||||
function(err, result)
|
||||
{
|
||||
assert.ifError(err);
|
||||
assert.equal(result[result.length - 1], expected);
|
||||
deferred.resolve();
|
||||
});
|
||||
}, {'defer': true})
|
||||
|
||||
|
||||
.add('asynckit.parallel', function(deferred)
|
||||
{
|
||||
var total = 0;
|
||||
|
||||
asynckit.parallel(source,
|
||||
function(i, cb)
|
||||
{
|
||||
setImmediate(function()
|
||||
{
|
||||
total += i;
|
||||
cb(null, total);
|
||||
});
|
||||
},
|
||||
function(err, result)
|
||||
{
|
||||
assert.ifError(err);
|
||||
assert.equal(result[result.length - 1], expected);
|
||||
deferred.resolve();
|
||||
});
|
||||
}, {'defer': true})
|
||||
|
||||
|
||||
// add listeners
|
||||
.on('cycle', function(ev)
|
||||
{
|
||||
console.log(String(ev.target));
|
||||
})
|
||||
.on('complete', function()
|
||||
{
|
||||
console.log('Fastest is ' + this.filter('fastest').map('name'));
|
||||
})
|
||||
// run async
|
||||
.run({ 'async': true });
|
||||
6
.claude/skills/教学日程查询/node_modules/asynckit/index.js
generated
vendored
Normal file
6
.claude/skills/教学日程查询/node_modules/asynckit/index.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports =
|
||||
{
|
||||
parallel : require('./parallel.js'),
|
||||
serial : require('./serial.js'),
|
||||
serialOrdered : require('./serialOrdered.js')
|
||||
};
|
||||
29
.claude/skills/教学日程查询/node_modules/asynckit/lib/abort.js
generated
vendored
Normal file
29
.claude/skills/教学日程查询/node_modules/asynckit/lib/abort.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// API
|
||||
module.exports = abort;
|
||||
|
||||
/**
|
||||
* Aborts leftover active jobs
|
||||
*
|
||||
* @param {object} state - current state object
|
||||
*/
|
||||
function abort(state)
|
||||
{
|
||||
Object.keys(state.jobs).forEach(clean.bind(state));
|
||||
|
||||
// reset leftover jobs
|
||||
state.jobs = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up leftover job by invoking abort function for the provided job id
|
||||
*
|
||||
* @this state
|
||||
* @param {string|number} key - job id to abort
|
||||
*/
|
||||
function clean(key)
|
||||
{
|
||||
if (typeof this.jobs[key] == 'function')
|
||||
{
|
||||
this.jobs[key]();
|
||||
}
|
||||
}
|
||||
34
.claude/skills/教学日程查询/node_modules/asynckit/lib/async.js
generated
vendored
Normal file
34
.claude/skills/教学日程查询/node_modules/asynckit/lib/async.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
var defer = require('./defer.js');
|
||||
|
||||
// API
|
||||
module.exports = async;
|
||||
|
||||
/**
|
||||
* Runs provided callback asynchronously
|
||||
* even if callback itself is not
|
||||
*
|
||||
* @param {function} callback - callback to invoke
|
||||
* @returns {function} - augmented callback
|
||||
*/
|
||||
function async(callback)
|
||||
{
|
||||
var isAsync = false;
|
||||
|
||||
// check if async happened
|
||||
defer(function() { isAsync = true; });
|
||||
|
||||
return function async_callback(err, result)
|
||||
{
|
||||
if (isAsync)
|
||||
{
|
||||
callback(err, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
defer(function nextTick_callback()
|
||||
{
|
||||
callback(err, result);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
26
.claude/skills/教学日程查询/node_modules/asynckit/lib/defer.js
generated
vendored
Normal file
26
.claude/skills/教学日程查询/node_modules/asynckit/lib/defer.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
module.exports = defer;
|
||||
|
||||
/**
|
||||
* Runs provided function on next iteration of the event loop
|
||||
*
|
||||
* @param {function} fn - function to run
|
||||
*/
|
||||
function defer(fn)
|
||||
{
|
||||
var nextTick = typeof setImmediate == 'function'
|
||||
? setImmediate
|
||||
: (
|
||||
typeof process == 'object' && typeof process.nextTick == 'function'
|
||||
? process.nextTick
|
||||
: null
|
||||
);
|
||||
|
||||
if (nextTick)
|
||||
{
|
||||
nextTick(fn);
|
||||
}
|
||||
else
|
||||
{
|
||||
setTimeout(fn, 0);
|
||||
}
|
||||
}
|
||||
75
.claude/skills/教学日程查询/node_modules/asynckit/lib/iterate.js
generated
vendored
Normal file
75
.claude/skills/教学日程查询/node_modules/asynckit/lib/iterate.js
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
var async = require('./async.js')
|
||||
, abort = require('./abort.js')
|
||||
;
|
||||
|
||||
// API
|
||||
module.exports = iterate;
|
||||
|
||||
/**
|
||||
* Iterates over each job object
|
||||
*
|
||||
* @param {array|object} list - array or object (named list) to iterate over
|
||||
* @param {function} iterator - iterator to run
|
||||
* @param {object} state - current job status
|
||||
* @param {function} callback - invoked when all elements processed
|
||||
*/
|
||||
function iterate(list, iterator, state, callback)
|
||||
{
|
||||
// store current index
|
||||
var key = state['keyedList'] ? state['keyedList'][state.index] : state.index;
|
||||
|
||||
state.jobs[key] = runJob(iterator, key, list[key], function(error, output)
|
||||
{
|
||||
// don't repeat yourself
|
||||
// skip secondary callbacks
|
||||
if (!(key in state.jobs))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// clean up jobs
|
||||
delete state.jobs[key];
|
||||
|
||||
if (error)
|
||||
{
|
||||
// don't process rest of the results
|
||||
// stop still active jobs
|
||||
// and reset the list
|
||||
abort(state);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.results[key] = output;
|
||||
}
|
||||
|
||||
// return salvaged results
|
||||
callback(error, state.results);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs iterator over provided job element
|
||||
*
|
||||
* @param {function} iterator - iterator to invoke
|
||||
* @param {string|number} key - key/index of the element in the list of jobs
|
||||
* @param {mixed} item - job description
|
||||
* @param {function} callback - invoked after iterator is done with the job
|
||||
* @returns {function|mixed} - job abort function or something else
|
||||
*/
|
||||
function runJob(iterator, key, item, callback)
|
||||
{
|
||||
var aborter;
|
||||
|
||||
// allow shortcut if iterator expects only two arguments
|
||||
if (iterator.length == 2)
|
||||
{
|
||||
aborter = iterator(item, async(callback));
|
||||
}
|
||||
// otherwise go with full three arguments
|
||||
else
|
||||
{
|
||||
aborter = iterator(item, key, async(callback));
|
||||
}
|
||||
|
||||
return aborter;
|
||||
}
|
||||
91
.claude/skills/教学日程查询/node_modules/asynckit/lib/readable_asynckit.js
generated
vendored
Normal file
91
.claude/skills/教学日程查询/node_modules/asynckit/lib/readable_asynckit.js
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
var streamify = require('./streamify.js')
|
||||
, defer = require('./defer.js')
|
||||
;
|
||||
|
||||
// API
|
||||
module.exports = ReadableAsyncKit;
|
||||
|
||||
/**
|
||||
* Base constructor for all streams
|
||||
* used to hold properties/methods
|
||||
*/
|
||||
function ReadableAsyncKit()
|
||||
{
|
||||
ReadableAsyncKit.super_.apply(this, arguments);
|
||||
|
||||
// list of active jobs
|
||||
this.jobs = {};
|
||||
|
||||
// add stream methods
|
||||
this.destroy = destroy;
|
||||
this._start = _start;
|
||||
this._read = _read;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys readable stream,
|
||||
* by aborting outstanding jobs
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function destroy()
|
||||
{
|
||||
if (this.destroyed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.destroyed = true;
|
||||
|
||||
if (typeof this.terminator == 'function')
|
||||
{
|
||||
this.terminator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts provided jobs in async manner
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function _start()
|
||||
{
|
||||
// first argument – runner function
|
||||
var runner = arguments[0]
|
||||
// take away first argument
|
||||
, args = Array.prototype.slice.call(arguments, 1)
|
||||
// second argument - input data
|
||||
, input = args[0]
|
||||
// last argument - result callback
|
||||
, endCb = streamify.callback.call(this, args[args.length - 1])
|
||||
;
|
||||
|
||||
args[args.length - 1] = endCb;
|
||||
// third argument - iterator
|
||||
args[1] = streamify.iterator.call(this, args[1]);
|
||||
|
||||
// allow time for proper setup
|
||||
defer(function()
|
||||
{
|
||||
if (!this.destroyed)
|
||||
{
|
||||
this.terminator = runner.apply(null, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
endCb(null, Array.isArray(input) ? [] : {});
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implement _read to comply with Readable streams
|
||||
* Doesn't really make sense for flowing object mode
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function _read()
|
||||
{
|
||||
|
||||
}
|
||||
25
.claude/skills/教学日程查询/node_modules/asynckit/lib/readable_parallel.js
generated
vendored
Normal file
25
.claude/skills/教学日程查询/node_modules/asynckit/lib/readable_parallel.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
var parallel = require('../parallel.js');
|
||||
|
||||
// API
|
||||
module.exports = ReadableParallel;
|
||||
|
||||
/**
|
||||
* Streaming wrapper to `asynckit.parallel`
|
||||
*
|
||||
* @param {array|object} list - array or object (named list) to iterate over
|
||||
* @param {function} iterator - iterator to run
|
||||
* @param {function} callback - invoked when all elements processed
|
||||
* @returns {stream.Readable#}
|
||||
*/
|
||||
function ReadableParallel(list, iterator, callback)
|
||||
{
|
||||
if (!(this instanceof ReadableParallel))
|
||||
{
|
||||
return new ReadableParallel(list, iterator, callback);
|
||||
}
|
||||
|
||||
// turn on object mode
|
||||
ReadableParallel.super_.call(this, {objectMode: true});
|
||||
|
||||
this._start(parallel, list, iterator, callback);
|
||||
}
|
||||
25
.claude/skills/教学日程查询/node_modules/asynckit/lib/readable_serial.js
generated
vendored
Normal file
25
.claude/skills/教学日程查询/node_modules/asynckit/lib/readable_serial.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
var serial = require('../serial.js');
|
||||
|
||||
// API
|
||||
module.exports = ReadableSerial;
|
||||
|
||||
/**
|
||||
* Streaming wrapper to `asynckit.serial`
|
||||
*
|
||||
* @param {array|object} list - array or object (named list) to iterate over
|
||||
* @param {function} iterator - iterator to run
|
||||
* @param {function} callback - invoked when all elements processed
|
||||
* @returns {stream.Readable#}
|
||||
*/
|
||||
function ReadableSerial(list, iterator, callback)
|
||||
{
|
||||
if (!(this instanceof ReadableSerial))
|
||||
{
|
||||
return new ReadableSerial(list, iterator, callback);
|
||||
}
|
||||
|
||||
// turn on object mode
|
||||
ReadableSerial.super_.call(this, {objectMode: true});
|
||||
|
||||
this._start(serial, list, iterator, callback);
|
||||
}
|
||||
29
.claude/skills/教学日程查询/node_modules/asynckit/lib/readable_serial_ordered.js
generated
vendored
Normal file
29
.claude/skills/教学日程查询/node_modules/asynckit/lib/readable_serial_ordered.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
var serialOrdered = require('../serialOrdered.js');
|
||||
|
||||
// API
|
||||
module.exports = ReadableSerialOrdered;
|
||||
// expose sort helpers
|
||||
module.exports.ascending = serialOrdered.ascending;
|
||||
module.exports.descending = serialOrdered.descending;
|
||||
|
||||
/**
|
||||
* Streaming wrapper to `asynckit.serialOrdered`
|
||||
*
|
||||
* @param {array|object} list - array or object (named list) to iterate over
|
||||
* @param {function} iterator - iterator to run
|
||||
* @param {function} sortMethod - custom sort function
|
||||
* @param {function} callback - invoked when all elements processed
|
||||
* @returns {stream.Readable#}
|
||||
*/
|
||||
function ReadableSerialOrdered(list, iterator, sortMethod, callback)
|
||||
{
|
||||
if (!(this instanceof ReadableSerialOrdered))
|
||||
{
|
||||
return new ReadableSerialOrdered(list, iterator, sortMethod, callback);
|
||||
}
|
||||
|
||||
// turn on object mode
|
||||
ReadableSerialOrdered.super_.call(this, {objectMode: true});
|
||||
|
||||
this._start(serialOrdered, list, iterator, sortMethod, callback);
|
||||
}
|
||||
37
.claude/skills/教学日程查询/node_modules/asynckit/lib/state.js
generated
vendored
Normal file
37
.claude/skills/教学日程查询/node_modules/asynckit/lib/state.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
// API
|
||||
module.exports = state;
|
||||
|
||||
/**
|
||||
* Creates initial state object
|
||||
* for iteration over list
|
||||
*
|
||||
* @param {array|object} list - list to iterate over
|
||||
* @param {function|null} sortMethod - function to use for keys sort,
|
||||
* or `null` to keep them as is
|
||||
* @returns {object} - initial state object
|
||||
*/
|
||||
function state(list, sortMethod)
|
||||
{
|
||||
var isNamedList = !Array.isArray(list)
|
||||
, initState =
|
||||
{
|
||||
index : 0,
|
||||
keyedList: isNamedList || sortMethod ? Object.keys(list) : null,
|
||||
jobs : {},
|
||||
results : isNamedList ? {} : [],
|
||||
size : isNamedList ? Object.keys(list).length : list.length
|
||||
}
|
||||
;
|
||||
|
||||
if (sortMethod)
|
||||
{
|
||||
// sort array keys based on it's values
|
||||
// sort object's keys just on own merit
|
||||
initState.keyedList.sort(isNamedList ? sortMethod : function(a, b)
|
||||
{
|
||||
return sortMethod(list[a], list[b]);
|
||||
});
|
||||
}
|
||||
|
||||
return initState;
|
||||
}
|
||||
141
.claude/skills/教学日程查询/node_modules/asynckit/lib/streamify.js
generated
vendored
Normal file
141
.claude/skills/教学日程查询/node_modules/asynckit/lib/streamify.js
generated
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
var async = require('./async.js');
|
||||
|
||||
// API
|
||||
module.exports = {
|
||||
iterator: wrapIterator,
|
||||
callback: wrapCallback
|
||||
};
|
||||
|
||||
/**
|
||||
* Wraps iterators with long signature
|
||||
*
|
||||
* @this ReadableAsyncKit#
|
||||
* @param {function} iterator - function to wrap
|
||||
* @returns {function} - wrapped function
|
||||
*/
|
||||
function wrapIterator(iterator)
|
||||
{
|
||||
var stream = this;
|
||||
|
||||
return function(item, key, cb)
|
||||
{
|
||||
var aborter
|
||||
, wrappedCb = async(wrapIteratorCallback.call(stream, cb, key))
|
||||
;
|
||||
|
||||
stream.jobs[key] = wrappedCb;
|
||||
|
||||
// it's either shortcut (item, cb)
|
||||
if (iterator.length == 2)
|
||||
{
|
||||
aborter = iterator(item, wrappedCb);
|
||||
}
|
||||
// or long format (item, key, cb)
|
||||
else
|
||||
{
|
||||
aborter = iterator(item, key, wrappedCb);
|
||||
}
|
||||
|
||||
return aborter;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps provided callback function
|
||||
* allowing to execute snitch function before
|
||||
* real callback
|
||||
*
|
||||
* @this ReadableAsyncKit#
|
||||
* @param {function} callback - function to wrap
|
||||
* @returns {function} - wrapped function
|
||||
*/
|
||||
function wrapCallback(callback)
|
||||
{
|
||||
var stream = this;
|
||||
|
||||
var wrapped = function(error, result)
|
||||
{
|
||||
return finisher.call(stream, error, result, callback);
|
||||
};
|
||||
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps provided iterator callback function
|
||||
* makes sure snitch only called once,
|
||||
* but passes secondary calls to the original callback
|
||||
*
|
||||
* @this ReadableAsyncKit#
|
||||
* @param {function} callback - callback to wrap
|
||||
* @param {number|string} key - iteration key
|
||||
* @returns {function} wrapped callback
|
||||
*/
|
||||
function wrapIteratorCallback(callback, key)
|
||||
{
|
||||
var stream = this;
|
||||
|
||||
return function(error, output)
|
||||
{
|
||||
// don't repeat yourself
|
||||
if (!(key in stream.jobs))
|
||||
{
|
||||
callback(error, output);
|
||||
return;
|
||||
}
|
||||
|
||||
// clean up jobs
|
||||
delete stream.jobs[key];
|
||||
|
||||
return streamer.call(stream, error, {key: key, value: output}, callback);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Stream wrapper for iterator callback
|
||||
*
|
||||
* @this ReadableAsyncKit#
|
||||
* @param {mixed} error - error response
|
||||
* @param {mixed} output - iterator output
|
||||
* @param {function} callback - callback that expects iterator results
|
||||
*/
|
||||
function streamer(error, output, callback)
|
||||
{
|
||||
if (error && !this.error)
|
||||
{
|
||||
this.error = error;
|
||||
this.pause();
|
||||
this.emit('error', error);
|
||||
// send back value only, as expected
|
||||
callback(error, output && output.value);
|
||||
return;
|
||||
}
|
||||
|
||||
// stream stuff
|
||||
this.push(output);
|
||||
|
||||
// back to original track
|
||||
// send back value only, as expected
|
||||
callback(error, output && output.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stream wrapper for finishing callback
|
||||
*
|
||||
* @this ReadableAsyncKit#
|
||||
* @param {mixed} error - error response
|
||||
* @param {mixed} output - iterator output
|
||||
* @param {function} callback - callback that expects final results
|
||||
*/
|
||||
function finisher(error, output, callback)
|
||||
{
|
||||
// signal end of the stream
|
||||
// only for successfully finished streams
|
||||
if (!error)
|
||||
{
|
||||
this.push(null);
|
||||
}
|
||||
|
||||
// back to original track
|
||||
callback(error, output);
|
||||
}
|
||||
29
.claude/skills/教学日程查询/node_modules/asynckit/lib/terminator.js
generated
vendored
Normal file
29
.claude/skills/教学日程查询/node_modules/asynckit/lib/terminator.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
var abort = require('./abort.js')
|
||||
, async = require('./async.js')
|
||||
;
|
||||
|
||||
// API
|
||||
module.exports = terminator;
|
||||
|
||||
/**
|
||||
* Terminates jobs in the attached state context
|
||||
*
|
||||
* @this AsyncKitState#
|
||||
* @param {function} callback - final callback to invoke after termination
|
||||
*/
|
||||
function terminator(callback)
|
||||
{
|
||||
if (!Object.keys(this.jobs).length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// fast forward iteration index
|
||||
this.index = this.size;
|
||||
|
||||
// abort jobs
|
||||
abort(this);
|
||||
|
||||
// send back results we have so far
|
||||
async(callback)(null, this.results);
|
||||
}
|
||||
63
.claude/skills/教学日程查询/node_modules/asynckit/package.json
generated
vendored
Normal file
63
.claude/skills/教学日程查询/node_modules/asynckit/package.json
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"name": "asynckit",
|
||||
"version": "0.4.0",
|
||||
"description": "Minimal async jobs utility library, with streams support",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"clean": "rimraf coverage",
|
||||
"lint": "eslint *.js lib/*.js test/*.js",
|
||||
"test": "istanbul cover --reporter=json tape -- 'test/test-*.js' | tap-spec",
|
||||
"win-test": "tape test/test-*.js",
|
||||
"browser": "browserify -t browserify-istanbul test/lib/browserify_adjustment.js test/test-*.js | obake --coverage | tap-spec",
|
||||
"report": "istanbul report",
|
||||
"size": "browserify index.js | size-table asynckit",
|
||||
"debug": "tape test/test-*.js"
|
||||
},
|
||||
"pre-commit": [
|
||||
"clean",
|
||||
"lint",
|
||||
"test",
|
||||
"browser",
|
||||
"report",
|
||||
"size"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/alexindigo/asynckit.git"
|
||||
},
|
||||
"keywords": [
|
||||
"async",
|
||||
"jobs",
|
||||
"parallel",
|
||||
"serial",
|
||||
"iterator",
|
||||
"array",
|
||||
"object",
|
||||
"stream",
|
||||
"destroy",
|
||||
"terminate",
|
||||
"abort"
|
||||
],
|
||||
"author": "Alex Indigo <iam@alexindigo.com>",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/alexindigo/asynckit/issues"
|
||||
},
|
||||
"homepage": "https://github.com/alexindigo/asynckit#readme",
|
||||
"devDependencies": {
|
||||
"browserify": "^13.0.0",
|
||||
"browserify-istanbul": "^2.0.0",
|
||||
"coveralls": "^2.11.9",
|
||||
"eslint": "^2.9.0",
|
||||
"istanbul": "^0.4.3",
|
||||
"obake": "^0.1.2",
|
||||
"phantomjs-prebuilt": "^2.1.7",
|
||||
"pre-commit": "^1.1.3",
|
||||
"reamde": "^1.1.0",
|
||||
"rimraf": "^2.5.2",
|
||||
"size-table": "^0.2.0",
|
||||
"tap-spec": "^4.1.1",
|
||||
"tape": "^4.5.1"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
43
.claude/skills/教学日程查询/node_modules/asynckit/parallel.js
generated
vendored
Normal file
43
.claude/skills/教学日程查询/node_modules/asynckit/parallel.js
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
var iterate = require('./lib/iterate.js')
|
||||
, initState = require('./lib/state.js')
|
||||
, terminator = require('./lib/terminator.js')
|
||||
;
|
||||
|
||||
// Public API
|
||||
module.exports = parallel;
|
||||
|
||||
/**
|
||||
* Runs iterator over provided array elements in parallel
|
||||
*
|
||||
* @param {array|object} list - array or object (named list) to iterate over
|
||||
* @param {function} iterator - iterator to run
|
||||
* @param {function} callback - invoked when all elements processed
|
||||
* @returns {function} - jobs terminator
|
||||
*/
|
||||
function parallel(list, iterator, callback)
|
||||
{
|
||||
var state = initState(list);
|
||||
|
||||
while (state.index < (state['keyedList'] || list).length)
|
||||
{
|
||||
iterate(list, iterator, state, function(error, result)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
callback(error, result);
|
||||
return;
|
||||
}
|
||||
|
||||
// looks like it's the last one
|
||||
if (Object.keys(state.jobs).length === 0)
|
||||
{
|
||||
callback(null, state.results);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
state.index++;
|
||||
}
|
||||
|
||||
return terminator.bind(state, callback);
|
||||
}
|
||||
17
.claude/skills/教学日程查询/node_modules/asynckit/serial.js
generated
vendored
Normal file
17
.claude/skills/教学日程查询/node_modules/asynckit/serial.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
var serialOrdered = require('./serialOrdered.js');
|
||||
|
||||
// Public API
|
||||
module.exports = serial;
|
||||
|
||||
/**
|
||||
* Runs iterator over provided array elements in series
|
||||
*
|
||||
* @param {array|object} list - array or object (named list) to iterate over
|
||||
* @param {function} iterator - iterator to run
|
||||
* @param {function} callback - invoked when all elements processed
|
||||
* @returns {function} - jobs terminator
|
||||
*/
|
||||
function serial(list, iterator, callback)
|
||||
{
|
||||
return serialOrdered(list, iterator, null, callback);
|
||||
}
|
||||
75
.claude/skills/教学日程查询/node_modules/asynckit/serialOrdered.js
generated
vendored
Normal file
75
.claude/skills/教学日程查询/node_modules/asynckit/serialOrdered.js
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
var iterate = require('./lib/iterate.js')
|
||||
, initState = require('./lib/state.js')
|
||||
, terminator = require('./lib/terminator.js')
|
||||
;
|
||||
|
||||
// Public API
|
||||
module.exports = serialOrdered;
|
||||
// sorting helpers
|
||||
module.exports.ascending = ascending;
|
||||
module.exports.descending = descending;
|
||||
|
||||
/**
|
||||
* Runs iterator over provided sorted array elements in series
|
||||
*
|
||||
* @param {array|object} list - array or object (named list) to iterate over
|
||||
* @param {function} iterator - iterator to run
|
||||
* @param {function} sortMethod - custom sort function
|
||||
* @param {function} callback - invoked when all elements processed
|
||||
* @returns {function} - jobs terminator
|
||||
*/
|
||||
function serialOrdered(list, iterator, sortMethod, callback)
|
||||
{
|
||||
var state = initState(list, sortMethod);
|
||||
|
||||
iterate(list, iterator, state, function iteratorHandler(error, result)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
callback(error, result);
|
||||
return;
|
||||
}
|
||||
|
||||
state.index++;
|
||||
|
||||
// are we there yet?
|
||||
if (state.index < (state['keyedList'] || list).length)
|
||||
{
|
||||
iterate(list, iterator, state, iteratorHandler);
|
||||
return;
|
||||
}
|
||||
|
||||
// done here
|
||||
callback(null, state.results);
|
||||
});
|
||||
|
||||
return terminator.bind(state, callback);
|
||||
}
|
||||
|
||||
/*
|
||||
* -- Sort methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* sort helper to sort array elements in ascending order
|
||||
*
|
||||
* @param {mixed} a - an item to compare
|
||||
* @param {mixed} b - an item to compare
|
||||
* @returns {number} - comparison result
|
||||
*/
|
||||
function ascending(a, b)
|
||||
{
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sort helper to sort array elements in descending order
|
||||
*
|
||||
* @param {mixed} a - an item to compare
|
||||
* @param {mixed} b - an item to compare
|
||||
* @returns {number} - comparison result
|
||||
*/
|
||||
function descending(a, b)
|
||||
{
|
||||
return -1 * ascending(a, b);
|
||||
}
|
||||
21
.claude/skills/教学日程查询/node_modules/asynckit/stream.js
generated
vendored
Normal file
21
.claude/skills/教学日程查询/node_modules/asynckit/stream.js
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
var inherits = require('util').inherits
|
||||
, Readable = require('stream').Readable
|
||||
, ReadableAsyncKit = require('./lib/readable_asynckit.js')
|
||||
, ReadableParallel = require('./lib/readable_parallel.js')
|
||||
, ReadableSerial = require('./lib/readable_serial.js')
|
||||
, ReadableSerialOrdered = require('./lib/readable_serial_ordered.js')
|
||||
;
|
||||
|
||||
// API
|
||||
module.exports =
|
||||
{
|
||||
parallel : ReadableParallel,
|
||||
serial : ReadableSerial,
|
||||
serialOrdered : ReadableSerialOrdered,
|
||||
};
|
||||
|
||||
inherits(ReadableAsyncKit, Readable);
|
||||
|
||||
inherits(ReadableParallel, ReadableAsyncKit);
|
||||
inherits(ReadableSerial, ReadableAsyncKit);
|
||||
inherits(ReadableSerialOrdered, ReadableAsyncKit);
|
||||
1650
.claude/skills/教学日程查询/node_modules/axios/CHANGELOG.md
generated
vendored
Normal file
1650
.claude/skills/教学日程查询/node_modules/axios/CHANGELOG.md
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
.claude/skills/教学日程查询/node_modules/axios/LICENSE
generated
vendored
Normal file
7
.claude/skills/教学日程查询/node_modules/axios/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# Copyright (c) 2014-present Matt Zabriskie & Collaborators
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
877
.claude/skills/教学日程查询/node_modules/axios/MIGRATION_GUIDE.md
generated
vendored
Normal file
877
.claude/skills/教学日程查询/node_modules/axios/MIGRATION_GUIDE.md
generated
vendored
Normal file
@@ -0,0 +1,877 @@
|
||||
# Axios Migration Guide
|
||||
|
||||
> **Migrating from Axios 0.x to 1.x**
|
||||
>
|
||||
> This guide helps developers upgrade from Axios 0.x to 1.x by documenting breaking changes, providing migration strategies, and offering solutions to common upgrade challenges.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Breaking Changes](#breaking-changes)
|
||||
- [Error Handling Migration](#error-handling-migration)
|
||||
- [API Changes](#api-changes)
|
||||
- [Configuration Changes](#configuration-changes)
|
||||
- [Migration Strategies](#migration-strategies)
|
||||
- [Common Patterns](#common-patterns)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Resources](#resources)
|
||||
|
||||
## Overview
|
||||
|
||||
Axios 1.x introduced several breaking changes to improve consistency, security, and developer experience. While these changes provide better error handling and more predictable behavior, they require code updates when migrating from 0.x versions.
|
||||
|
||||
### Key Changes Summary
|
||||
|
||||
| Area | 0.x Behavior | 1.x Behavior | Impact |
|
||||
|------|--------------|--------------|--------|
|
||||
| Error Handling | Selective throwing | Consistent throwing | High |
|
||||
| JSON Parsing | Lenient | Strict | Medium |
|
||||
| Browser Support | IE11+ | Modern browsers | Low-Medium |
|
||||
| TypeScript | Partial | Full support | Low |
|
||||
|
||||
### Migration Complexity
|
||||
|
||||
- **Simple applications**: 1-2 hours
|
||||
- **Medium applications**: 1-2 days
|
||||
- **Large applications with complex error handling**: 3-5 days
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
### 1. Error Handling Changes
|
||||
|
||||
**The most significant change in Axios 1.x is how errors are handled.**
|
||||
|
||||
#### 0.x Behavior
|
||||
```javascript
|
||||
// Axios 0.x - Some HTTP error codes didn't throw
|
||||
axios.get('/api/data')
|
||||
.then(response => {
|
||||
// Response interceptor could handle all errors
|
||||
console.log('Success:', response.data);
|
||||
});
|
||||
|
||||
// Response interceptor handled everything
|
||||
axios.interceptors.response.use(
|
||||
response => response,
|
||||
error => {
|
||||
handleError(error);
|
||||
// Error was "handled" and didn't propagate
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
#### 1.x Behavior
|
||||
```javascript
|
||||
// Axios 1.x - All HTTP errors throw consistently
|
||||
axios.get('/api/data')
|
||||
.then(response => {
|
||||
console.log('Success:', response.data);
|
||||
})
|
||||
.catch(error => {
|
||||
// Must handle errors at call site or they propagate
|
||||
console.error('Request failed:', error);
|
||||
});
|
||||
|
||||
// Response interceptor must re-throw or return rejected promise
|
||||
axios.interceptors.response.use(
|
||||
response => response,
|
||||
error => {
|
||||
handleError(error);
|
||||
// Must explicitly handle propagation
|
||||
return Promise.reject(error); // or throw error;
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
#### Impact
|
||||
- **Response interceptors** can no longer "swallow" errors silently
|
||||
- **Every API call** must handle errors explicitly or they become unhandled promise rejections
|
||||
- **Centralized error handling** requires new patterns
|
||||
|
||||
### 2. JSON Parsing Changes
|
||||
|
||||
#### 0.x Behavior
|
||||
```javascript
|
||||
// Axios 0.x - Lenient JSON parsing
|
||||
// Would attempt to parse even invalid JSON
|
||||
response.data; // Might contain partial data or fallbacks
|
||||
```
|
||||
|
||||
#### 1.x Behavior
|
||||
```javascript
|
||||
// Axios 1.x - Strict JSON parsing
|
||||
// Throws clear errors for invalid JSON
|
||||
try {
|
||||
const data = response.data;
|
||||
} catch (error) {
|
||||
// Handle JSON parsing errors explicitly
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Request/Response Transform Changes
|
||||
|
||||
#### 0.x Behavior
|
||||
```javascript
|
||||
// Implicit transformations with some edge cases
|
||||
transformRequest: [function (data) {
|
||||
// Less predictable behavior
|
||||
return data;
|
||||
}]
|
||||
```
|
||||
|
||||
#### 1.x Behavior
|
||||
```javascript
|
||||
// More consistent transformation pipeline
|
||||
transformRequest: [function (data, headers) {
|
||||
// Headers parameter always available
|
||||
// More predictable behavior
|
||||
return data;
|
||||
}]
|
||||
```
|
||||
|
||||
### 4. Browser Support Changes
|
||||
|
||||
- **0.x**: Supported IE11 and older browsers
|
||||
- **1.x**: Requires modern browsers with Promise support
|
||||
- **Polyfills**: May be needed for older browser support
|
||||
|
||||
## Error Handling Migration
|
||||
|
||||
The error handling changes are the most complex part of migrating to Axios 1.x. Here are proven strategies:
|
||||
|
||||
### Strategy 1: Centralized Error Handling with Error Boundary
|
||||
|
||||
```javascript
|
||||
// Create a centralized error handler
|
||||
class ApiErrorHandler {
|
||||
constructor() {
|
||||
this.setupInterceptors();
|
||||
}
|
||||
|
||||
setupInterceptors() {
|
||||
axios.interceptors.response.use(
|
||||
response => response,
|
||||
error => {
|
||||
// Centralized error processing
|
||||
this.processError(error);
|
||||
|
||||
// Return a resolved promise with error info for handled errors
|
||||
if (this.isHandledError(error)) {
|
||||
return Promise.resolve({
|
||||
data: null,
|
||||
error: this.normalizeError(error),
|
||||
handled: true
|
||||
});
|
||||
}
|
||||
|
||||
// Re-throw unhandled errors
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
processError(error) {
|
||||
// Log errors
|
||||
console.error('API Error:', error);
|
||||
|
||||
// Show user notifications
|
||||
if (error.response?.status === 401) {
|
||||
this.handleAuthError();
|
||||
} else if (error.response?.status >= 500) {
|
||||
this.showErrorNotification('Server error occurred');
|
||||
}
|
||||
}
|
||||
|
||||
isHandledError(error) {
|
||||
// Define which errors are "handled" centrally
|
||||
const handledStatuses = [401, 403, 404, 422, 500, 502, 503];
|
||||
return handledStatuses.includes(error.response?.status);
|
||||
}
|
||||
|
||||
normalizeError(error) {
|
||||
return {
|
||||
status: error.response?.status,
|
||||
message: error.response?.data?.message || error.message,
|
||||
code: error.response?.data?.code || error.code
|
||||
};
|
||||
}
|
||||
|
||||
handleAuthError() {
|
||||
// Redirect to login, clear tokens, etc.
|
||||
localStorage.removeItem('token');
|
||||
window.location.href = '/login';
|
||||
}
|
||||
|
||||
showErrorNotification(message) {
|
||||
// Show user-friendly error message
|
||||
console.error(message); // Replace with your notification system
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize globally
|
||||
const errorHandler = new ApiErrorHandler();
|
||||
|
||||
// Usage in components/services
|
||||
async function fetchUserData(userId) {
|
||||
try {
|
||||
const response = await axios.get(`/api/users/${userId}`);
|
||||
|
||||
// Check if error was handled centrally
|
||||
if (response.handled) {
|
||||
return { data: null, error: response.error };
|
||||
}
|
||||
|
||||
return { data: response.data, error: null };
|
||||
} catch (error) {
|
||||
// Unhandled errors still need local handling
|
||||
return { data: null, error: { message: 'Unexpected error occurred' } };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Strategy 2: Wrapper Function Pattern
|
||||
|
||||
```javascript
|
||||
// Create a wrapper that provides 0.x-like behavior
|
||||
function createApiWrapper() {
|
||||
const api = axios.create();
|
||||
|
||||
// Add response interceptor for centralized handling
|
||||
api.interceptors.response.use(
|
||||
response => response,
|
||||
error => {
|
||||
// Handle common errors centrally
|
||||
if (error.response?.status === 401) {
|
||||
// Handle auth errors
|
||||
handleAuthError();
|
||||
}
|
||||
|
||||
if (error.response?.status >= 500) {
|
||||
// Handle server errors
|
||||
showServerErrorNotification();
|
||||
}
|
||||
|
||||
// Always reject to maintain error propagation
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// Wrapper function that mimics 0.x behavior
|
||||
function safeRequest(requestConfig, options = {}) {
|
||||
return api(requestConfig)
|
||||
.then(response => response)
|
||||
.catch(error => {
|
||||
if (options.suppressErrors) {
|
||||
// Return error info instead of throwing
|
||||
return {
|
||||
data: null,
|
||||
error: {
|
||||
status: error.response?.status,
|
||||
message: error.response?.data?.message || error.message
|
||||
}
|
||||
};
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
return { safeRequest, axios: api };
|
||||
}
|
||||
|
||||
// Usage
|
||||
const { safeRequest } = createApiWrapper();
|
||||
|
||||
// For calls where you want centralized error handling
|
||||
const result = await safeRequest(
|
||||
{ method: 'get', url: '/api/data' },
|
||||
{ suppressErrors: true }
|
||||
);
|
||||
|
||||
if (result.error) {
|
||||
// Handle error case
|
||||
console.log('Request failed:', result.error.message);
|
||||
} else {
|
||||
// Handle success case
|
||||
console.log('Data:', result.data);
|
||||
}
|
||||
```
|
||||
|
||||
### Strategy 3: Global Error Handler with Custom Events
|
||||
|
||||
```javascript
|
||||
// Set up global error handling with events
|
||||
class GlobalErrorHandler extends EventTarget {
|
||||
constructor() {
|
||||
super();
|
||||
this.setupInterceptors();
|
||||
}
|
||||
|
||||
setupInterceptors() {
|
||||
axios.interceptors.response.use(
|
||||
response => response,
|
||||
error => {
|
||||
// Emit custom event for global handling
|
||||
this.dispatchEvent(new CustomEvent('apiError', {
|
||||
detail: { error, timestamp: new Date() }
|
||||
}));
|
||||
|
||||
// Always reject to maintain proper error flow
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const globalErrorHandler = new GlobalErrorHandler();
|
||||
|
||||
// Set up global listeners
|
||||
globalErrorHandler.addEventListener('apiError', (event) => {
|
||||
const { error } = event.detail;
|
||||
|
||||
// Centralized error logic
|
||||
if (error.response?.status === 401) {
|
||||
handleAuthError();
|
||||
}
|
||||
|
||||
if (error.response?.status >= 500) {
|
||||
showErrorNotification('Server error occurred');
|
||||
}
|
||||
});
|
||||
|
||||
// Usage remains clean
|
||||
async function apiCall() {
|
||||
try {
|
||||
const response = await axios.get('/api/data');
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
// Error was already handled globally
|
||||
// Just handle component-specific logic
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API Changes
|
||||
|
||||
### Request Configuration
|
||||
|
||||
#### 0.x to 1.x Changes
|
||||
```javascript
|
||||
// 0.x - Some properties had different defaults
|
||||
const config = {
|
||||
timeout: 0, // No timeout by default
|
||||
maxContentLength: -1, // No limit
|
||||
};
|
||||
|
||||
// 1.x - More secure defaults
|
||||
const config = {
|
||||
timeout: 0, // Still no timeout, but easier to configure
|
||||
maxContentLength: 2000, // Default limit for security
|
||||
maxBodyLength: 2000, // New property
|
||||
};
|
||||
```
|
||||
|
||||
### Response Object
|
||||
|
||||
The response object structure remains largely the same, but error responses are more consistent:
|
||||
|
||||
```javascript
|
||||
// Both 0.x and 1.x
|
||||
response = {
|
||||
data: {}, // Response body
|
||||
status: 200, // HTTP status
|
||||
statusText: 'OK', // HTTP status message
|
||||
headers: {}, // Response headers
|
||||
config: {}, // Request config
|
||||
request: {} // Request object
|
||||
};
|
||||
|
||||
// Error responses are more consistent in 1.x
|
||||
error.response = {
|
||||
data: {}, // Error response body
|
||||
status: 404, // HTTP error status
|
||||
statusText: 'Not Found',
|
||||
headers: {},
|
||||
config: {},
|
||||
request: {}
|
||||
};
|
||||
```
|
||||
|
||||
## Configuration Changes
|
||||
|
||||
### Default Configuration Updates
|
||||
|
||||
```javascript
|
||||
// 0.x defaults
|
||||
axios.defaults.timeout = 0; // No timeout
|
||||
axios.defaults.maxContentLength = -1; // No limit
|
||||
|
||||
// 1.x defaults (more secure)
|
||||
axios.defaults.timeout = 0; // Still no timeout
|
||||
axios.defaults.maxContentLength = 2000; // 2MB limit
|
||||
axios.defaults.maxBodyLength = 2000; // 2MB limit
|
||||
```
|
||||
|
||||
### Instance Configuration
|
||||
|
||||
```javascript
|
||||
// 0.x - Instance creation
|
||||
const api = axios.create({
|
||||
baseURL: 'https://api.example.com',
|
||||
timeout: 1000,
|
||||
});
|
||||
|
||||
// 1.x - Same API, but more options available
|
||||
const api = axios.create({
|
||||
baseURL: 'https://api.example.com',
|
||||
timeout: 1000,
|
||||
maxBodyLength: Infinity, // Override default if needed
|
||||
maxContentLength: Infinity,
|
||||
});
|
||||
```
|
||||
|
||||
## Migration Strategies
|
||||
|
||||
### Step-by-Step Migration Process
|
||||
|
||||
#### Phase 1: Preparation
|
||||
1. **Audit Current Error Handling**
|
||||
```bash
|
||||
# Find all axios usage
|
||||
grep -r "axios\." src/
|
||||
grep -r "\.catch" src/
|
||||
grep -r "interceptors" src/
|
||||
```
|
||||
|
||||
2. **Identify Patterns**
|
||||
- Response interceptors that handle errors
|
||||
- Components that rely on centralized error handling
|
||||
- Authentication and retry logic
|
||||
|
||||
3. **Create Test Cases**
|
||||
```javascript
|
||||
// Test current error handling behavior
|
||||
describe('Error Handling Migration', () => {
|
||||
it('should handle 401 errors consistently', async () => {
|
||||
// Test authentication error flows
|
||||
});
|
||||
|
||||
it('should handle 500 errors with user feedback', async () => {
|
||||
// Test server error handling
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
#### Phase 2: Implementation
|
||||
1. **Update Dependencies**
|
||||
```bash
|
||||
npm update axios
|
||||
```
|
||||
|
||||
2. **Implement New Error Handling**
|
||||
- Choose one of the strategies above
|
||||
- Update response interceptors
|
||||
- Add error handling to API calls
|
||||
|
||||
3. **Update Authentication Logic**
|
||||
```javascript
|
||||
// 0.x pattern
|
||||
axios.interceptors.response.use(null, error => {
|
||||
if (error.response?.status === 401) {
|
||||
logout();
|
||||
// Error was "handled"
|
||||
}
|
||||
});
|
||||
|
||||
// 1.x pattern
|
||||
axios.interceptors.response.use(
|
||||
response => response,
|
||||
error => {
|
||||
if (error.response?.status === 401) {
|
||||
logout();
|
||||
}
|
||||
return Promise.reject(error); // Always propagate
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
#### Phase 3: Testing and Validation
|
||||
1. **Test Error Scenarios**
|
||||
- Network failures
|
||||
- HTTP error codes (401, 403, 404, 500, etc.)
|
||||
- Timeout errors
|
||||
- JSON parsing errors
|
||||
|
||||
2. **Validate User Experience**
|
||||
- Error messages are shown appropriately
|
||||
- Authentication redirects work
|
||||
- Loading states are handled correctly
|
||||
|
||||
### Gradual Migration Approach
|
||||
|
||||
For large applications, consider gradual migration:
|
||||
|
||||
```javascript
|
||||
// Create a compatibility layer
|
||||
const axiosCompat = {
|
||||
// Use new axios instance for new code
|
||||
v1: axios.create({
|
||||
// 1.x configuration
|
||||
}),
|
||||
|
||||
// Wrapper for legacy code
|
||||
legacy: createLegacyWrapper(axios.create({
|
||||
// Configuration that mimics 0.x behavior
|
||||
}))
|
||||
};
|
||||
|
||||
function createLegacyWrapper(axiosInstance) {
|
||||
// Add interceptors that provide 0.x-like behavior
|
||||
axiosInstance.interceptors.response.use(
|
||||
response => response,
|
||||
error => {
|
||||
// Handle errors in 0.x style for legacy code
|
||||
handleLegacyError(error);
|
||||
// Don't propagate certain errors
|
||||
if (shouldSuppressError(error)) {
|
||||
return Promise.resolve({ data: null, error: true });
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
return axiosInstance;
|
||||
}
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Authentication Interceptors
|
||||
|
||||
#### Updated Authentication Pattern
|
||||
```javascript
|
||||
// Token refresh interceptor for 1.x
|
||||
let isRefreshing = false;
|
||||
let refreshSubscribers = [];
|
||||
|
||||
function subscribeTokenRefresh(cb) {
|
||||
refreshSubscribers.push(cb);
|
||||
}
|
||||
|
||||
function onTokenRefreshed(token) {
|
||||
refreshSubscribers.forEach(cb => cb(token));
|
||||
refreshSubscribers = [];
|
||||
}
|
||||
|
||||
axios.interceptors.response.use(
|
||||
response => response,
|
||||
async error => {
|
||||
const originalRequest = error.config;
|
||||
|
||||
if (error.response?.status === 401 && !originalRequest._retry) {
|
||||
if (isRefreshing) {
|
||||
// Wait for token refresh
|
||||
return new Promise(resolve => {
|
||||
subscribeTokenRefresh(token => {
|
||||
originalRequest.headers.Authorization = `Bearer ${token}`;
|
||||
resolve(axios(originalRequest));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
originalRequest._retry = true;
|
||||
isRefreshing = true;
|
||||
|
||||
try {
|
||||
const newToken = await refreshToken();
|
||||
onTokenRefreshed(newToken);
|
||||
isRefreshing = false;
|
||||
|
||||
originalRequest.headers.Authorization = `Bearer ${newToken}`;
|
||||
return axios(originalRequest);
|
||||
} catch (refreshError) {
|
||||
isRefreshing = false;
|
||||
logout();
|
||||
return Promise.reject(refreshError);
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
### Retry Logic
|
||||
|
||||
```javascript
|
||||
// Retry interceptor for 1.x
|
||||
function createRetryInterceptor(maxRetries = 3, retryDelay = 1000) {
|
||||
return axios.interceptors.response.use(
|
||||
response => response,
|
||||
async error => {
|
||||
const config = error.config;
|
||||
|
||||
if (!config || !config.retry) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
config.__retryCount = config.__retryCount || 0;
|
||||
|
||||
if (config.__retryCount >= maxRetries) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
config.__retryCount += 1;
|
||||
|
||||
// Exponential backoff
|
||||
const delay = retryDelay * Math.pow(2, config.__retryCount - 1);
|
||||
await new Promise(resolve => setTimeout(resolve, delay));
|
||||
|
||||
return axios(config);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Usage
|
||||
const api = axios.create();
|
||||
createRetryInterceptor(3, 1000);
|
||||
|
||||
// Make request with retry
|
||||
api.get('/api/data', { retry: true });
|
||||
```
|
||||
|
||||
### Loading State Management
|
||||
|
||||
```javascript
|
||||
// Loading interceptor for 1.x
|
||||
class LoadingManager {
|
||||
constructor() {
|
||||
this.requests = new Set();
|
||||
this.setupInterceptors();
|
||||
}
|
||||
|
||||
setupInterceptors() {
|
||||
axios.interceptors.request.use(config => {
|
||||
this.requests.add(config);
|
||||
this.updateLoadingState();
|
||||
return config;
|
||||
});
|
||||
|
||||
axios.interceptors.response.use(
|
||||
response => {
|
||||
this.requests.delete(response.config);
|
||||
this.updateLoadingState();
|
||||
return response;
|
||||
},
|
||||
error => {
|
||||
this.requests.delete(error.config);
|
||||
this.updateLoadingState();
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
updateLoadingState() {
|
||||
const isLoading = this.requests.size > 0;
|
||||
// Update your loading UI
|
||||
document.body.classList.toggle('loading', isLoading);
|
||||
}
|
||||
}
|
||||
|
||||
const loadingManager = new LoadingManager();
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Migration Issues
|
||||
|
||||
#### Issue 1: Unhandled Promise Rejections
|
||||
|
||||
**Problem:**
|
||||
```javascript
|
||||
// This pattern worked in 0.x but causes unhandled rejections in 1.x
|
||||
axios.get('/api/data'); // No .catch() handler
|
||||
```
|
||||
|
||||
**Solution:**
|
||||
```javascript
|
||||
// Always handle promises
|
||||
axios.get('/api/data')
|
||||
.catch(error => {
|
||||
// Handle error appropriately
|
||||
console.error('Request failed:', error.message);
|
||||
});
|
||||
|
||||
// Or use async/await with try/catch
|
||||
async function fetchData() {
|
||||
try {
|
||||
const response = await axios.get('/api/data');
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error('Request failed:', error.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Issue 2: Response Interceptors Not "Handling" Errors
|
||||
|
||||
**Problem:**
|
||||
```javascript
|
||||
// 0.x style - interceptor "handled" errors
|
||||
axios.interceptors.response.use(null, error => {
|
||||
showErrorMessage(error.message);
|
||||
// Error was considered "handled"
|
||||
});
|
||||
```
|
||||
|
||||
**Solution:**
|
||||
```javascript
|
||||
// 1.x style - explicitly control error propagation
|
||||
axios.interceptors.response.use(
|
||||
response => response,
|
||||
error => {
|
||||
showErrorMessage(error.message);
|
||||
|
||||
// Choose whether to propagate the error
|
||||
if (shouldPropagateError(error)) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
// Return success-like response for "handled" errors
|
||||
return Promise.resolve({
|
||||
data: null,
|
||||
handled: true,
|
||||
error: normalizeError(error)
|
||||
});
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
#### Issue 3: JSON Parsing Errors
|
||||
|
||||
**Problem:**
|
||||
```javascript
|
||||
// 1.x is stricter about JSON parsing
|
||||
// This might throw where 0.x was lenient
|
||||
const data = response.data;
|
||||
```
|
||||
|
||||
**Solution:**
|
||||
```javascript
|
||||
// Add response transformer for better error handling
|
||||
axios.defaults.transformResponse = [
|
||||
function (data) {
|
||||
if (typeof data === 'string') {
|
||||
try {
|
||||
return JSON.parse(data);
|
||||
} catch (e) {
|
||||
// Handle JSON parsing errors gracefully
|
||||
console.warn('Invalid JSON response:', data);
|
||||
return { error: 'Invalid JSON', rawData: data };
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
];
|
||||
```
|
||||
|
||||
#### Issue 4: TypeScript Errors After Upgrade
|
||||
|
||||
**Problem:**
|
||||
```typescript
|
||||
// TypeScript errors after upgrade
|
||||
const response = await axios.get('/api/data');
|
||||
// Property 'someProperty' does not exist on type 'any'
|
||||
```
|
||||
|
||||
**Solution:**
|
||||
```typescript
|
||||
// Define proper interfaces
|
||||
interface ApiResponse {
|
||||
data: any;
|
||||
message: string;
|
||||
success: boolean;
|
||||
}
|
||||
|
||||
const response = await axios.get<ApiResponse>('/api/data');
|
||||
// Now properly typed
|
||||
console.log(response.data.data);
|
||||
```
|
||||
|
||||
### Debug Migration Issues
|
||||
|
||||
#### Enable Debug Logging
|
||||
```javascript
|
||||
// Add request/response logging
|
||||
axios.interceptors.request.use(config => {
|
||||
console.log('Request:', config);
|
||||
return config;
|
||||
});
|
||||
|
||||
axios.interceptors.response.use(
|
||||
response => {
|
||||
console.log('Response:', response);
|
||||
return response;
|
||||
},
|
||||
error => {
|
||||
console.log('Error:', error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
#### Compare Behavior
|
||||
```javascript
|
||||
// Create side-by-side comparison during migration
|
||||
const axios0x = require('axios-0x'); // Keep old version for testing
|
||||
const axios1x = require('axios');
|
||||
|
||||
async function compareRequests(config) {
|
||||
try {
|
||||
const [result0x, result1x] = await Promise.allSettled([
|
||||
axios0x(config),
|
||||
axios1x(config)
|
||||
]);
|
||||
|
||||
console.log('0.x result:', result0x);
|
||||
console.log('1.x result:', result1x);
|
||||
} catch (error) {
|
||||
console.log('Comparison error:', error);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
### Official Documentation
|
||||
- [Axios 1.x Documentation](https://axios-http.com/)
|
||||
- [Axios GitHub Repository](https://github.com/axios/axios)
|
||||
- [Axios Changelog](https://github.com/axios/axios/blob/main/CHANGELOG.md)
|
||||
|
||||
### Migration Tools
|
||||
- [Axios Migration Codemod](https://github.com/axios/axios-migration-codemod) *(if available)*
|
||||
- [ESLint Rules for Axios 1.x](https://github.com/axios/eslint-plugin-axios) *(if available)*
|
||||
|
||||
### Community Resources
|
||||
- [Stack Overflow - Axios Migration Questions](https://stackoverflow.com/questions/tagged/axios+migration)
|
||||
- [GitHub Discussions](https://github.com/axios/axios/discussions)
|
||||
- [Axios Discord Community](https://discord.gg/axios) *(if available)*
|
||||
|
||||
### Related Issues
|
||||
- [Error Handling Changes Discussion](https://github.com/axios/axios/issues/7208)
|
||||
- [Migration Guide Request](https://github.com/axios/axios/issues/xxxx) *(link to related issues)*
|
||||
|
||||
---
|
||||
|
||||
## Need Help?
|
||||
|
||||
If you encounter issues during migration that aren't covered in this guide:
|
||||
|
||||
1. **Search existing issues** in the [Axios GitHub repository](https://github.com/axios/axios/issues)
|
||||
2. **Ask questions** in [GitHub Discussions](https://github.com/axios/axios/discussions)
|
||||
3. **Contribute improvements** to this migration guide
|
||||
|
||||
---
|
||||
|
||||
*This migration guide is maintained by the community. If you find errors or have suggestions, please [open an issue](https://github.com/axios/axios/issues) or submit a pull request.*
|
||||
2055
.claude/skills/教学日程查询/node_modules/axios/README.md
generated
vendored
Normal file
2055
.claude/skills/教学日程查询/node_modules/axios/README.md
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4546
.claude/skills/教学日程查询/node_modules/axios/dist/axios.js
generated
vendored
Normal file
4546
.claude/skills/教学日程查询/node_modules/axios/dist/axios.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
.claude/skills/教学日程查询/node_modules/axios/dist/axios.js.map
generated
vendored
Normal file
1
.claude/skills/教学日程查询/node_modules/axios/dist/axios.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
5
.claude/skills/教学日程查询/node_modules/axios/dist/axios.min.js
generated
vendored
Normal file
5
.claude/skills/教学日程查询/node_modules/axios/dist/axios.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
.claude/skills/教学日程查询/node_modules/axios/dist/axios.min.js.map
generated
vendored
Normal file
1
.claude/skills/教学日程查询/node_modules/axios/dist/axios.min.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
4338
.claude/skills/教学日程查询/node_modules/axios/dist/browser/axios.cjs
generated
vendored
Normal file
4338
.claude/skills/教学日程查询/node_modules/axios/dist/browser/axios.cjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
.claude/skills/教学日程查询/node_modules/axios/dist/browser/axios.cjs.map
generated
vendored
Normal file
1
.claude/skills/教学日程查询/node_modules/axios/dist/browser/axios.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
4358
.claude/skills/教学日程查询/node_modules/axios/dist/esm/axios.js
generated
vendored
Normal file
4358
.claude/skills/教学日程查询/node_modules/axios/dist/esm/axios.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
.claude/skills/教学日程查询/node_modules/axios/dist/esm/axios.js.map
generated
vendored
Normal file
1
.claude/skills/教学日程查询/node_modules/axios/dist/esm/axios.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
3
.claude/skills/教学日程查询/node_modules/axios/dist/esm/axios.min.js
generated
vendored
Normal file
3
.claude/skills/教学日程查询/node_modules/axios/dist/esm/axios.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
.claude/skills/教学日程查询/node_modules/axios/dist/esm/axios.min.js.map
generated
vendored
Normal file
1
.claude/skills/教学日程查询/node_modules/axios/dist/esm/axios.min.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
4989
.claude/skills/教学日程查询/node_modules/axios/dist/node/axios.cjs
generated
vendored
Normal file
4989
.claude/skills/教学日程查询/node_modules/axios/dist/node/axios.cjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
.claude/skills/教学日程查询/node_modules/axios/dist/node/axios.cjs.map
generated
vendored
Normal file
1
.claude/skills/教学日程查询/node_modules/axios/dist/node/axios.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
703
.claude/skills/教学日程查询/node_modules/axios/index.d.cts
generated
vendored
Normal file
703
.claude/skills/教学日程查询/node_modules/axios/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,703 @@
|
||||
interface RawAxiosHeaders {
|
||||
[key: string]: axios.AxiosHeaderValue;
|
||||
}
|
||||
|
||||
type MethodsHeaders = Partial<
|
||||
{
|
||||
[Key in axios.Method as Lowercase<Key>]: AxiosHeaders;
|
||||
} & { common: AxiosHeaders }
|
||||
>;
|
||||
|
||||
type AxiosHeaderMatcher =
|
||||
| string
|
||||
| RegExp
|
||||
| ((this: AxiosHeaders, value: string, name: string) => boolean);
|
||||
|
||||
type AxiosHeaderParser = (this: AxiosHeaders, value: axios.AxiosHeaderValue, header: string) => any;
|
||||
|
||||
type CommonRequestHeadersList =
|
||||
| 'Accept'
|
||||
| 'Content-Length'
|
||||
| 'User-Agent'
|
||||
| 'Content-Encoding'
|
||||
| 'Authorization'
|
||||
| 'Location';
|
||||
|
||||
type ContentType =
|
||||
| axios.AxiosHeaderValue
|
||||
| 'text/html'
|
||||
| 'text/plain'
|
||||
| 'multipart/form-data'
|
||||
| 'application/json'
|
||||
| 'application/x-www-form-urlencoded'
|
||||
| 'application/octet-stream';
|
||||
|
||||
type CommonResponseHeadersList =
|
||||
| 'Server'
|
||||
| 'Content-Type'
|
||||
| 'Content-Length'
|
||||
| 'Cache-Control'
|
||||
| 'Content-Encoding';
|
||||
|
||||
type CommonResponseHeaderKey = CommonResponseHeadersList | Lowercase<CommonResponseHeadersList>;
|
||||
|
||||
type BrowserProgressEvent = any;
|
||||
|
||||
declare class AxiosHeaders {
|
||||
constructor(headers?: RawAxiosHeaders | AxiosHeaders | string);
|
||||
|
||||
[key: string]: any;
|
||||
|
||||
set(
|
||||
headerName?: string,
|
||||
value?: axios.AxiosHeaderValue,
|
||||
rewrite?: boolean | AxiosHeaderMatcher
|
||||
): AxiosHeaders;
|
||||
set(headers?: RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean): AxiosHeaders;
|
||||
|
||||
get(headerName: string, parser: RegExp): RegExpExecArray | null;
|
||||
get(headerName: string, matcher?: true | AxiosHeaderParser): axios.AxiosHeaderValue;
|
||||
|
||||
has(header: string, matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
clear(matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
normalize(format: boolean): AxiosHeaders;
|
||||
|
||||
concat(
|
||||
...targets: Array<AxiosHeaders | RawAxiosHeaders | string | undefined | null>
|
||||
): AxiosHeaders;
|
||||
|
||||
toJSON(asStrings?: boolean): RawAxiosHeaders;
|
||||
|
||||
static from(thing?: AxiosHeaders | RawAxiosHeaders | string): AxiosHeaders;
|
||||
|
||||
static accessor(header: string | string[]): AxiosHeaders;
|
||||
|
||||
static concat(
|
||||
...targets: Array<AxiosHeaders | RawAxiosHeaders | string | undefined | null>
|
||||
): AxiosHeaders;
|
||||
|
||||
setContentType(value: ContentType, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders;
|
||||
getContentType(parser?: RegExp): RegExpExecArray | null;
|
||||
getContentType(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue;
|
||||
hasContentType(matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
setContentLength(
|
||||
value: axios.AxiosHeaderValue,
|
||||
rewrite?: boolean | AxiosHeaderMatcher
|
||||
): AxiosHeaders;
|
||||
getContentLength(parser?: RegExp): RegExpExecArray | null;
|
||||
getContentLength(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue;
|
||||
hasContentLength(matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
setAccept(value: axios.AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders;
|
||||
getAccept(parser?: RegExp): RegExpExecArray | null;
|
||||
getAccept(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue;
|
||||
hasAccept(matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
setUserAgent(value: axios.AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders;
|
||||
getUserAgent(parser?: RegExp): RegExpExecArray | null;
|
||||
getUserAgent(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue;
|
||||
hasUserAgent(matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
setContentEncoding(
|
||||
value: axios.AxiosHeaderValue,
|
||||
rewrite?: boolean | AxiosHeaderMatcher
|
||||
): AxiosHeaders;
|
||||
getContentEncoding(parser?: RegExp): RegExpExecArray | null;
|
||||
getContentEncoding(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue;
|
||||
hasContentEncoding(matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
setAuthorization(
|
||||
value: axios.AxiosHeaderValue,
|
||||
rewrite?: boolean | AxiosHeaderMatcher
|
||||
): AxiosHeaders;
|
||||
getAuthorization(parser?: RegExp): RegExpExecArray | null;
|
||||
getAuthorization(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue;
|
||||
hasAuthorization(matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
getSetCookie(): string[];
|
||||
|
||||
[Symbol.iterator](): IterableIterator<[string, axios.AxiosHeaderValue]>;
|
||||
}
|
||||
|
||||
declare class AxiosError<T = unknown, D = any> extends Error {
|
||||
constructor(
|
||||
message?: string,
|
||||
code?: string,
|
||||
config?: axios.InternalAxiosRequestConfig<D>,
|
||||
request?: any,
|
||||
response?: axios.AxiosResponse<T, D>
|
||||
);
|
||||
|
||||
config?: axios.InternalAxiosRequestConfig<D>;
|
||||
code?: string;
|
||||
request?: any;
|
||||
response?: axios.AxiosResponse<T, D>;
|
||||
isAxiosError: boolean;
|
||||
status?: number;
|
||||
toJSON: () => object;
|
||||
cause?: Error;
|
||||
event?: BrowserProgressEvent;
|
||||
static from<T = unknown, D = any>(
|
||||
error: Error | unknown,
|
||||
code?: string,
|
||||
config?: axios.InternalAxiosRequestConfig<D>,
|
||||
request?: any,
|
||||
response?: axios.AxiosResponse<T, D>,
|
||||
customProps?: object
|
||||
): AxiosError<T, D>;
|
||||
static readonly ERR_FR_TOO_MANY_REDIRECTS = 'ERR_FR_TOO_MANY_REDIRECTS';
|
||||
static readonly ERR_BAD_OPTION_VALUE = 'ERR_BAD_OPTION_VALUE';
|
||||
static readonly ERR_BAD_OPTION = 'ERR_BAD_OPTION';
|
||||
static readonly ERR_NETWORK = 'ERR_NETWORK';
|
||||
static readonly ERR_DEPRECATED = 'ERR_DEPRECATED';
|
||||
static readonly ERR_BAD_RESPONSE = 'ERR_BAD_RESPONSE';
|
||||
static readonly ERR_BAD_REQUEST = 'ERR_BAD_REQUEST';
|
||||
static readonly ERR_NOT_SUPPORT = 'ERR_NOT_SUPPORT';
|
||||
static readonly ERR_INVALID_URL = 'ERR_INVALID_URL';
|
||||
static readonly ERR_CANCELED = 'ERR_CANCELED';
|
||||
static readonly ERR_FORM_DATA_DEPTH_EXCEEDED = 'ERR_FORM_DATA_DEPTH_EXCEEDED';
|
||||
static readonly ECONNABORTED = 'ECONNABORTED';
|
||||
static readonly ETIMEDOUT = 'ETIMEDOUT';
|
||||
}
|
||||
|
||||
declare class CanceledError<T> extends AxiosError<T> {}
|
||||
|
||||
declare class Axios {
|
||||
constructor(config?: axios.AxiosRequestConfig);
|
||||
defaults: axios.AxiosDefaults;
|
||||
interceptors: {
|
||||
request: axios.AxiosInterceptorManager<axios.InternalAxiosRequestConfig>;
|
||||
response: axios.AxiosInterceptorManager<axios.AxiosResponse>;
|
||||
};
|
||||
getUri(config?: axios.AxiosRequestConfig): string;
|
||||
request<T = any, R = axios.AxiosResponse<T>, D = any>(
|
||||
config: axios.AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
get<T = any, R = axios.AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
config?: axios.AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
delete<T = any, R = axios.AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
config?: axios.AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
head<T = any, R = axios.AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
config?: axios.AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
options<T = any, R = axios.AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
config?: axios.AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
post<T = any, R = axios.AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
data?: D,
|
||||
config?: axios.AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
put<T = any, R = axios.AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
data?: D,
|
||||
config?: axios.AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
patch<T = any, R = axios.AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
data?: D,
|
||||
config?: axios.AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
postForm<T = any, R = axios.AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
data?: D,
|
||||
config?: axios.AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
putForm<T = any, R = axios.AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
data?: D,
|
||||
config?: axios.AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
patchForm<T = any, R = axios.AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
data?: D,
|
||||
config?: axios.AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
}
|
||||
|
||||
declare enum HttpStatusCode {
|
||||
Continue = 100,
|
||||
SwitchingProtocols = 101,
|
||||
Processing = 102,
|
||||
EarlyHints = 103,
|
||||
Ok = 200,
|
||||
Created = 201,
|
||||
Accepted = 202,
|
||||
NonAuthoritativeInformation = 203,
|
||||
NoContent = 204,
|
||||
ResetContent = 205,
|
||||
PartialContent = 206,
|
||||
MultiStatus = 207,
|
||||
AlreadyReported = 208,
|
||||
ImUsed = 226,
|
||||
MultipleChoices = 300,
|
||||
MovedPermanently = 301,
|
||||
Found = 302,
|
||||
SeeOther = 303,
|
||||
NotModified = 304,
|
||||
UseProxy = 305,
|
||||
Unused = 306,
|
||||
TemporaryRedirect = 307,
|
||||
PermanentRedirect = 308,
|
||||
BadRequest = 400,
|
||||
Unauthorized = 401,
|
||||
PaymentRequired = 402,
|
||||
Forbidden = 403,
|
||||
NotFound = 404,
|
||||
MethodNotAllowed = 405,
|
||||
NotAcceptable = 406,
|
||||
ProxyAuthenticationRequired = 407,
|
||||
RequestTimeout = 408,
|
||||
Conflict = 409,
|
||||
Gone = 410,
|
||||
LengthRequired = 411,
|
||||
PreconditionFailed = 412,
|
||||
PayloadTooLarge = 413,
|
||||
UriTooLong = 414,
|
||||
UnsupportedMediaType = 415,
|
||||
RangeNotSatisfiable = 416,
|
||||
ExpectationFailed = 417,
|
||||
ImATeapot = 418,
|
||||
MisdirectedRequest = 421,
|
||||
UnprocessableEntity = 422,
|
||||
Locked = 423,
|
||||
FailedDependency = 424,
|
||||
TooEarly = 425,
|
||||
UpgradeRequired = 426,
|
||||
PreconditionRequired = 428,
|
||||
TooManyRequests = 429,
|
||||
RequestHeaderFieldsTooLarge = 431,
|
||||
UnavailableForLegalReasons = 451,
|
||||
InternalServerError = 500,
|
||||
NotImplemented = 501,
|
||||
BadGateway = 502,
|
||||
ServiceUnavailable = 503,
|
||||
GatewayTimeout = 504,
|
||||
HttpVersionNotSupported = 505,
|
||||
VariantAlsoNegotiates = 506,
|
||||
InsufficientStorage = 507,
|
||||
LoopDetected = 508,
|
||||
NotExtended = 510,
|
||||
NetworkAuthenticationRequired = 511,
|
||||
}
|
||||
|
||||
type InternalAxiosError<T = unknown, D = any> = AxiosError<T, D>;
|
||||
|
||||
declare namespace axios {
|
||||
type AxiosError<T = unknown, D = any> = InternalAxiosError<T, D>;
|
||||
|
||||
type RawAxiosRequestHeaders = Partial<
|
||||
RawAxiosHeaders & {
|
||||
[Key in CommonRequestHeadersList]: AxiosHeaderValue;
|
||||
} & {
|
||||
'Content-Type': ContentType;
|
||||
}
|
||||
>;
|
||||
|
||||
type AxiosRequestHeaders = RawAxiosRequestHeaders & AxiosHeaders;
|
||||
|
||||
type AxiosHeaderValue = AxiosHeaders | string | string[] | number | boolean | null;
|
||||
|
||||
type RawCommonResponseHeaders = {
|
||||
[Key in CommonResponseHeaderKey]: AxiosHeaderValue;
|
||||
} & {
|
||||
'set-cookie': string[];
|
||||
};
|
||||
|
||||
type RawAxiosResponseHeaders = Partial<RawAxiosHeaders & RawCommonResponseHeaders>;
|
||||
|
||||
type AxiosResponseHeaders = RawAxiosResponseHeaders & AxiosHeaders;
|
||||
|
||||
interface AxiosRequestTransformer {
|
||||
(this: InternalAxiosRequestConfig, data: any, headers: AxiosRequestHeaders): any;
|
||||
}
|
||||
|
||||
interface AxiosResponseTransformer {
|
||||
(
|
||||
this: InternalAxiosRequestConfig,
|
||||
data: any,
|
||||
headers: AxiosResponseHeaders,
|
||||
status?: number
|
||||
): any;
|
||||
}
|
||||
|
||||
interface AxiosAdapter {
|
||||
(config: InternalAxiosRequestConfig): AxiosPromise;
|
||||
}
|
||||
|
||||
interface AxiosBasicCredentials {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
interface AxiosProxyConfig {
|
||||
host: string;
|
||||
port: number;
|
||||
auth?: AxiosBasicCredentials;
|
||||
protocol?: string;
|
||||
}
|
||||
|
||||
type UppercaseMethod =
|
||||
| 'GET'
|
||||
| 'DELETE'
|
||||
| 'HEAD'
|
||||
| 'OPTIONS'
|
||||
| 'POST'
|
||||
| 'PUT'
|
||||
| 'PATCH'
|
||||
| 'PURGE'
|
||||
| 'LINK'
|
||||
| 'UNLINK';
|
||||
|
||||
type Method = (UppercaseMethod | Lowercase<UppercaseMethod>) & {};
|
||||
|
||||
type ResponseType = 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream' | 'formdata';
|
||||
|
||||
type UppercaseResponseEncoding =
|
||||
| 'ASCII'
|
||||
| 'ANSI'
|
||||
| 'BINARY'
|
||||
| 'BASE64'
|
||||
| 'BASE64URL'
|
||||
| 'HEX'
|
||||
| 'LATIN1'
|
||||
| 'UCS-2'
|
||||
| 'UCS2'
|
||||
| 'UTF-8'
|
||||
| 'UTF8'
|
||||
| 'UTF16LE';
|
||||
|
||||
type responseEncoding = (UppercaseResponseEncoding | Lowercase<UppercaseResponseEncoding>) & {};
|
||||
|
||||
interface TransitionalOptions {
|
||||
silentJSONParsing?: boolean;
|
||||
forcedJSONParsing?: boolean;
|
||||
clarifyTimeoutError?: boolean;
|
||||
legacyInterceptorReqResOrdering?: boolean;
|
||||
}
|
||||
|
||||
interface GenericAbortSignal {
|
||||
readonly aborted: boolean;
|
||||
onabort?: ((...args: any) => any) | null;
|
||||
addEventListener?: (...args: any) => any;
|
||||
removeEventListener?: (...args: any) => any;
|
||||
}
|
||||
|
||||
interface FormDataVisitorHelpers {
|
||||
defaultVisitor: SerializerVisitor;
|
||||
convertValue: (value: any) => any;
|
||||
isVisitable: (value: any) => boolean;
|
||||
}
|
||||
|
||||
interface SerializerVisitor {
|
||||
(
|
||||
this: GenericFormData,
|
||||
value: any,
|
||||
key: string | number,
|
||||
path: null | Array<string | number>,
|
||||
helpers: FormDataVisitorHelpers
|
||||
): boolean;
|
||||
}
|
||||
|
||||
interface SerializerOptions {
|
||||
visitor?: SerializerVisitor;
|
||||
dots?: boolean;
|
||||
metaTokens?: boolean;
|
||||
indexes?: boolean | null;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line
|
||||
interface FormSerializerOptions extends SerializerOptions {}
|
||||
|
||||
interface ParamEncoder {
|
||||
(value: any, defaultEncoder: (value: any) => any): any;
|
||||
}
|
||||
|
||||
interface CustomParamsSerializer {
|
||||
(params: Record<string, any>, options?: ParamsSerializerOptions): string;
|
||||
}
|
||||
|
||||
interface ParamsSerializerOptions extends SerializerOptions {
|
||||
encode?: ParamEncoder;
|
||||
serialize?: CustomParamsSerializer;
|
||||
}
|
||||
|
||||
type MaxUploadRate = number;
|
||||
|
||||
type MaxDownloadRate = number;
|
||||
|
||||
interface AxiosProgressEvent {
|
||||
loaded: number;
|
||||
total?: number;
|
||||
progress?: number;
|
||||
bytes: number;
|
||||
rate?: number;
|
||||
estimated?: number;
|
||||
upload?: boolean;
|
||||
download?: boolean;
|
||||
event?: BrowserProgressEvent;
|
||||
lengthComputable: boolean;
|
||||
}
|
||||
|
||||
type Milliseconds = number;
|
||||
|
||||
type AxiosAdapterName = 'fetch' | 'xhr' | 'http' | (string & {});
|
||||
|
||||
type AxiosAdapterConfig = AxiosAdapter | AxiosAdapterName;
|
||||
|
||||
type AddressFamily = 4 | 6 | undefined;
|
||||
|
||||
interface LookupAddressEntry {
|
||||
address: string;
|
||||
family?: AddressFamily;
|
||||
}
|
||||
|
||||
type LookupAddress = string | LookupAddressEntry;
|
||||
|
||||
interface AxiosRequestConfig<D = any> {
|
||||
url?: string;
|
||||
method?: Method | string;
|
||||
baseURL?: string;
|
||||
allowAbsoluteUrls?: boolean;
|
||||
transformRequest?: AxiosRequestTransformer | AxiosRequestTransformer[];
|
||||
transformResponse?: AxiosResponseTransformer | AxiosResponseTransformer[];
|
||||
headers?: (RawAxiosRequestHeaders & MethodsHeaders) | AxiosHeaders;
|
||||
params?: any;
|
||||
paramsSerializer?: ParamsSerializerOptions | CustomParamsSerializer;
|
||||
data?: D;
|
||||
timeout?: Milliseconds;
|
||||
timeoutErrorMessage?: string;
|
||||
withCredentials?: boolean;
|
||||
adapter?: AxiosAdapterConfig | AxiosAdapterConfig[];
|
||||
auth?: AxiosBasicCredentials;
|
||||
responseType?: ResponseType;
|
||||
responseEncoding?: responseEncoding | string;
|
||||
xsrfCookieName?: string;
|
||||
xsrfHeaderName?: string;
|
||||
onUploadProgress?: (progressEvent: AxiosProgressEvent) => void;
|
||||
onDownloadProgress?: (progressEvent: AxiosProgressEvent) => void;
|
||||
maxContentLength?: number;
|
||||
validateStatus?: ((status: number) => boolean) | null;
|
||||
maxBodyLength?: number;
|
||||
maxRedirects?: number;
|
||||
maxRate?: number | [MaxUploadRate, MaxDownloadRate];
|
||||
beforeRedirect?: (
|
||||
options: Record<string, any>,
|
||||
responseDetails: { headers: Record<string, string>; statusCode: HttpStatusCode }
|
||||
) => void;
|
||||
socketPath?: string | null;
|
||||
allowedSocketPaths?: string | string[] | null;
|
||||
transport?: any;
|
||||
httpAgent?: any;
|
||||
httpsAgent?: any;
|
||||
proxy?: AxiosProxyConfig | false;
|
||||
cancelToken?: CancelToken;
|
||||
decompress?: boolean;
|
||||
transitional?: TransitionalOptions;
|
||||
signal?: GenericAbortSignal;
|
||||
insecureHTTPParser?: boolean;
|
||||
env?: {
|
||||
FormData?: new (...args: any[]) => object;
|
||||
fetch?: (input: URL | Request | string, init?: RequestInit) => Promise<Response>;
|
||||
Request?: new (input: URL | Request | string, init?: RequestInit) => Request;
|
||||
Response?: new (
|
||||
body?: ArrayBuffer | ArrayBufferView | Blob | FormData | URLSearchParams | string | null,
|
||||
init?: ResponseInit
|
||||
) => Response;
|
||||
};
|
||||
formSerializer?: FormSerializerOptions;
|
||||
family?: AddressFamily;
|
||||
lookup?:
|
||||
| ((
|
||||
hostname: string,
|
||||
options: object,
|
||||
cb: (
|
||||
err: Error | null,
|
||||
address: LookupAddress | LookupAddress[],
|
||||
family?: AddressFamily
|
||||
) => void
|
||||
) => void)
|
||||
| ((
|
||||
hostname: string,
|
||||
options: object
|
||||
) => Promise<
|
||||
| [address: LookupAddressEntry | LookupAddressEntry[], family?: AddressFamily]
|
||||
| LookupAddress
|
||||
>);
|
||||
withXSRFToken?: boolean | ((config: InternalAxiosRequestConfig) => boolean | undefined);
|
||||
fetchOptions?:
|
||||
| Omit<RequestInit, 'body' | 'headers' | 'method' | 'signal'>
|
||||
| Record<string, any>;
|
||||
httpVersion?: 1 | 2;
|
||||
http2Options?: Record<string, any> & {
|
||||
sessionTimeout?: number;
|
||||
};
|
||||
}
|
||||
|
||||
// Alias
|
||||
type RawAxiosRequestConfig<D = any> = AxiosRequestConfig<D>;
|
||||
|
||||
interface InternalAxiosRequestConfig<D = any> extends AxiosRequestConfig<D> {
|
||||
headers: AxiosRequestHeaders;
|
||||
}
|
||||
|
||||
interface HeadersDefaults {
|
||||
common: RawAxiosRequestHeaders;
|
||||
delete: RawAxiosRequestHeaders;
|
||||
get: RawAxiosRequestHeaders;
|
||||
head: RawAxiosRequestHeaders;
|
||||
post: RawAxiosRequestHeaders;
|
||||
put: RawAxiosRequestHeaders;
|
||||
patch: RawAxiosRequestHeaders;
|
||||
options?: RawAxiosRequestHeaders;
|
||||
purge?: RawAxiosRequestHeaders;
|
||||
link?: RawAxiosRequestHeaders;
|
||||
unlink?: RawAxiosRequestHeaders;
|
||||
}
|
||||
|
||||
interface AxiosDefaults<D = any> extends Omit<AxiosRequestConfig<D>, 'headers'> {
|
||||
headers: HeadersDefaults;
|
||||
}
|
||||
|
||||
interface CreateAxiosDefaults<D = any> extends Omit<AxiosRequestConfig<D>, 'headers'> {
|
||||
headers?: RawAxiosRequestHeaders | AxiosHeaders | Partial<HeadersDefaults>;
|
||||
}
|
||||
|
||||
interface AxiosResponse<T = any, D = any, H = {}> {
|
||||
data: T;
|
||||
status: number;
|
||||
statusText: string;
|
||||
headers: (H & RawAxiosResponseHeaders) | AxiosResponseHeaders;
|
||||
config: InternalAxiosRequestConfig<D>;
|
||||
request?: any;
|
||||
}
|
||||
|
||||
type AxiosPromise<T = any> = Promise<AxiosResponse<T>>;
|
||||
|
||||
interface CancelStatic {
|
||||
new (message?: string): Cancel;
|
||||
}
|
||||
|
||||
interface Cancel {
|
||||
message: string | undefined;
|
||||
}
|
||||
|
||||
interface Canceler {
|
||||
(message?: string, config?: AxiosRequestConfig, request?: any): void;
|
||||
}
|
||||
|
||||
interface CancelTokenStatic {
|
||||
new (executor: (cancel: Canceler) => void): CancelToken;
|
||||
source(): CancelTokenSource;
|
||||
}
|
||||
|
||||
interface CancelToken {
|
||||
promise: Promise<Cancel>;
|
||||
reason?: Cancel;
|
||||
throwIfRequested(): void;
|
||||
}
|
||||
|
||||
interface CancelTokenSource {
|
||||
token: CancelToken;
|
||||
cancel: Canceler;
|
||||
}
|
||||
|
||||
interface AxiosInterceptorOptions {
|
||||
synchronous?: boolean;
|
||||
runWhen?: ((config: InternalAxiosRequestConfig) => boolean) | null;
|
||||
}
|
||||
|
||||
type AxiosInterceptorFulfilled<T> = (value: T) => T | Promise<T>;
|
||||
type AxiosInterceptorRejected = (error: any) => any;
|
||||
|
||||
type AxiosRequestInterceptorUse<T> = (
|
||||
onFulfilled?: AxiosInterceptorFulfilled<T> | null,
|
||||
onRejected?: AxiosInterceptorRejected | null,
|
||||
options?: AxiosInterceptorOptions
|
||||
) => number;
|
||||
|
||||
type AxiosResponseInterceptorUse<T> = (
|
||||
onFulfilled?: AxiosInterceptorFulfilled<T> | null,
|
||||
onRejected?: AxiosInterceptorRejected | null
|
||||
) => number;
|
||||
|
||||
interface AxiosInterceptorHandler<T> {
|
||||
fulfilled: AxiosInterceptorFulfilled<T>;
|
||||
rejected?: AxiosInterceptorRejected;
|
||||
synchronous: boolean;
|
||||
runWhen?: ((config: InternalAxiosRequestConfig) => boolean) | null;
|
||||
}
|
||||
|
||||
interface AxiosInterceptorManager<V> {
|
||||
use: V extends AxiosResponse ? AxiosResponseInterceptorUse<V> : AxiosRequestInterceptorUse<V>;
|
||||
eject(id: number): void;
|
||||
clear(): void;
|
||||
handlers?: Array<AxiosInterceptorHandler<V>>;
|
||||
}
|
||||
|
||||
interface AxiosInstance extends Axios {
|
||||
<T = any, R = AxiosResponse<T>, D = any>(config: AxiosRequestConfig<D>): Promise<R>;
|
||||
<T = any, R = AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
config?: AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
|
||||
create(config?: CreateAxiosDefaults): AxiosInstance;
|
||||
defaults: Omit<AxiosDefaults, 'headers'> & {
|
||||
headers: HeadersDefaults & {
|
||||
[key: string]: AxiosHeaderValue;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
interface GenericFormData {
|
||||
append(name: string, value: any, options?: any): any;
|
||||
}
|
||||
|
||||
interface GenericHTMLFormElement {
|
||||
name: string;
|
||||
method: string;
|
||||
submit(): void;
|
||||
}
|
||||
|
||||
interface AxiosStatic extends AxiosInstance {
|
||||
Cancel: CancelStatic;
|
||||
CancelToken: CancelTokenStatic;
|
||||
Axios: typeof Axios;
|
||||
AxiosError: typeof AxiosError;
|
||||
CanceledError: typeof CanceledError;
|
||||
HttpStatusCode: typeof HttpStatusCode;
|
||||
readonly VERSION: string;
|
||||
isCancel(value: any): value is Cancel;
|
||||
all<T>(values: Array<T | Promise<T>>): Promise<T[]>;
|
||||
spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R;
|
||||
isAxiosError<T = any, D = any>(payload: any): payload is AxiosError<T, D>;
|
||||
toFormData(
|
||||
sourceObj: object,
|
||||
targetFormData?: GenericFormData,
|
||||
options?: FormSerializerOptions
|
||||
): GenericFormData;
|
||||
formToJSON(form: GenericFormData | GenericHTMLFormElement): object;
|
||||
getAdapter(adapters: AxiosAdapterConfig | AxiosAdapterConfig[] | undefined): AxiosAdapter;
|
||||
AxiosHeaders: typeof AxiosHeaders;
|
||||
mergeConfig<D = any>(
|
||||
config1: AxiosRequestConfig<D>,
|
||||
config2: AxiosRequestConfig<D>
|
||||
): AxiosRequestConfig<D>;
|
||||
}
|
||||
}
|
||||
|
||||
declare const axios: axios.AxiosStatic;
|
||||
|
||||
export = axios;
|
||||
717
.claude/skills/教学日程查询/node_modules/axios/index.d.ts
generated
vendored
Normal file
717
.claude/skills/教学日程查询/node_modules/axios/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,717 @@
|
||||
// TypeScript Version: 4.7
|
||||
type StringLiteralsOrString<Literals extends string> = Literals | (string & {});
|
||||
|
||||
export type AxiosHeaderValue = AxiosHeaders | string | string[] | number | boolean | null;
|
||||
|
||||
interface RawAxiosHeaders {
|
||||
[key: string]: AxiosHeaderValue;
|
||||
}
|
||||
|
||||
type MethodsHeaders = Partial<
|
||||
{
|
||||
[Key in Method as Lowercase<Key>]: AxiosHeaders;
|
||||
} & { common: AxiosHeaders }
|
||||
>;
|
||||
|
||||
type AxiosHeaderMatcher =
|
||||
| string
|
||||
| RegExp
|
||||
| ((this: AxiosHeaders, value: string, name: string) => boolean);
|
||||
|
||||
type AxiosHeaderParser = (this: AxiosHeaders, value: AxiosHeaderValue, header: string) => any;
|
||||
|
||||
export class AxiosHeaders {
|
||||
constructor(headers?: RawAxiosHeaders | AxiosHeaders | string);
|
||||
|
||||
[key: string]: any;
|
||||
|
||||
set(
|
||||
headerName?: string,
|
||||
value?: AxiosHeaderValue,
|
||||
rewrite?: boolean | AxiosHeaderMatcher
|
||||
): AxiosHeaders;
|
||||
set(headers?: RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean): AxiosHeaders;
|
||||
|
||||
get(headerName: string, parser: RegExp): RegExpExecArray | null;
|
||||
get(headerName: string, matcher?: true | AxiosHeaderParser): AxiosHeaderValue;
|
||||
|
||||
has(header: string, matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
clear(matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
normalize(format: boolean): AxiosHeaders;
|
||||
|
||||
concat(
|
||||
...targets: Array<AxiosHeaders | RawAxiosHeaders | string | undefined | null>
|
||||
): AxiosHeaders;
|
||||
|
||||
toJSON(asStrings?: boolean): RawAxiosHeaders;
|
||||
|
||||
static from(thing?: AxiosHeaders | RawAxiosHeaders | string): AxiosHeaders;
|
||||
|
||||
static accessor(header: string | string[]): AxiosHeaders;
|
||||
|
||||
static concat(
|
||||
...targets: Array<AxiosHeaders | RawAxiosHeaders | string | undefined | null>
|
||||
): AxiosHeaders;
|
||||
|
||||
setContentType(value: ContentType, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders;
|
||||
getContentType(parser?: RegExp): RegExpExecArray | null;
|
||||
getContentType(matcher?: AxiosHeaderMatcher): AxiosHeaderValue;
|
||||
hasContentType(matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
setContentLength(value: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders;
|
||||
getContentLength(parser?: RegExp): RegExpExecArray | null;
|
||||
getContentLength(matcher?: AxiosHeaderMatcher): AxiosHeaderValue;
|
||||
hasContentLength(matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
setAccept(value: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders;
|
||||
getAccept(parser?: RegExp): RegExpExecArray | null;
|
||||
getAccept(matcher?: AxiosHeaderMatcher): AxiosHeaderValue;
|
||||
hasAccept(matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
setUserAgent(value: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders;
|
||||
getUserAgent(parser?: RegExp): RegExpExecArray | null;
|
||||
getUserAgent(matcher?: AxiosHeaderMatcher): AxiosHeaderValue;
|
||||
hasUserAgent(matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
setContentEncoding(value: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders;
|
||||
getContentEncoding(parser?: RegExp): RegExpExecArray | null;
|
||||
getContentEncoding(matcher?: AxiosHeaderMatcher): AxiosHeaderValue;
|
||||
hasContentEncoding(matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
setAuthorization(value: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders;
|
||||
getAuthorization(parser?: RegExp): RegExpExecArray | null;
|
||||
getAuthorization(matcher?: AxiosHeaderMatcher): AxiosHeaderValue;
|
||||
hasAuthorization(matcher?: AxiosHeaderMatcher): boolean;
|
||||
|
||||
getSetCookie(): string[];
|
||||
|
||||
[Symbol.iterator](): IterableIterator<[string, AxiosHeaderValue]>;
|
||||
}
|
||||
|
||||
type CommonRequestHeadersList =
|
||||
| 'Accept'
|
||||
| 'Content-Length'
|
||||
| 'User-Agent'
|
||||
| 'Content-Encoding'
|
||||
| 'Authorization'
|
||||
| 'Location';
|
||||
|
||||
type ContentType =
|
||||
| AxiosHeaderValue
|
||||
| 'text/html'
|
||||
| 'text/plain'
|
||||
| 'multipart/form-data'
|
||||
| 'application/json'
|
||||
| 'application/x-www-form-urlencoded'
|
||||
| 'application/octet-stream';
|
||||
|
||||
export type RawAxiosRequestHeaders = Partial<
|
||||
RawAxiosHeaders & {
|
||||
[Key in CommonRequestHeadersList]: AxiosHeaderValue;
|
||||
} & {
|
||||
'Content-Type': ContentType;
|
||||
}
|
||||
>;
|
||||
|
||||
export type AxiosRequestHeaders = RawAxiosRequestHeaders & AxiosHeaders;
|
||||
|
||||
type CommonResponseHeadersList =
|
||||
| 'Server'
|
||||
| 'Content-Type'
|
||||
| 'Content-Length'
|
||||
| 'Cache-Control'
|
||||
| 'Content-Encoding';
|
||||
|
||||
type CommonResponseHeaderKey = CommonResponseHeadersList | Lowercase<CommonResponseHeadersList>;
|
||||
|
||||
type RawCommonResponseHeaders = {
|
||||
[Key in CommonResponseHeaderKey]: AxiosHeaderValue;
|
||||
} & {
|
||||
'set-cookie': string[];
|
||||
};
|
||||
|
||||
export type RawAxiosResponseHeaders = Partial<RawAxiosHeaders & RawCommonResponseHeaders>;
|
||||
|
||||
export type AxiosResponseHeaders = RawAxiosResponseHeaders & AxiosHeaders;
|
||||
|
||||
export interface AxiosRequestTransformer {
|
||||
(this: InternalAxiosRequestConfig, data: any, headers: AxiosRequestHeaders): any;
|
||||
}
|
||||
|
||||
export interface AxiosResponseTransformer {
|
||||
(
|
||||
this: InternalAxiosRequestConfig,
|
||||
data: any,
|
||||
headers: AxiosResponseHeaders,
|
||||
status?: number
|
||||
): any;
|
||||
}
|
||||
|
||||
export interface AxiosAdapter {
|
||||
(config: InternalAxiosRequestConfig): AxiosPromise;
|
||||
}
|
||||
|
||||
export interface AxiosBasicCredentials {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface AxiosProxyConfig {
|
||||
host: string;
|
||||
port: number;
|
||||
auth?: AxiosBasicCredentials;
|
||||
protocol?: string;
|
||||
}
|
||||
|
||||
export enum HttpStatusCode {
|
||||
Continue = 100,
|
||||
SwitchingProtocols = 101,
|
||||
Processing = 102,
|
||||
EarlyHints = 103,
|
||||
Ok = 200,
|
||||
Created = 201,
|
||||
Accepted = 202,
|
||||
NonAuthoritativeInformation = 203,
|
||||
NoContent = 204,
|
||||
ResetContent = 205,
|
||||
PartialContent = 206,
|
||||
MultiStatus = 207,
|
||||
AlreadyReported = 208,
|
||||
ImUsed = 226,
|
||||
MultipleChoices = 300,
|
||||
MovedPermanently = 301,
|
||||
Found = 302,
|
||||
SeeOther = 303,
|
||||
NotModified = 304,
|
||||
UseProxy = 305,
|
||||
Unused = 306,
|
||||
TemporaryRedirect = 307,
|
||||
PermanentRedirect = 308,
|
||||
BadRequest = 400,
|
||||
Unauthorized = 401,
|
||||
PaymentRequired = 402,
|
||||
Forbidden = 403,
|
||||
NotFound = 404,
|
||||
MethodNotAllowed = 405,
|
||||
NotAcceptable = 406,
|
||||
ProxyAuthenticationRequired = 407,
|
||||
RequestTimeout = 408,
|
||||
Conflict = 409,
|
||||
Gone = 410,
|
||||
LengthRequired = 411,
|
||||
PreconditionFailed = 412,
|
||||
PayloadTooLarge = 413,
|
||||
UriTooLong = 414,
|
||||
UnsupportedMediaType = 415,
|
||||
RangeNotSatisfiable = 416,
|
||||
ExpectationFailed = 417,
|
||||
ImATeapot = 418,
|
||||
MisdirectedRequest = 421,
|
||||
UnprocessableEntity = 422,
|
||||
Locked = 423,
|
||||
FailedDependency = 424,
|
||||
TooEarly = 425,
|
||||
UpgradeRequired = 426,
|
||||
PreconditionRequired = 428,
|
||||
TooManyRequests = 429,
|
||||
RequestHeaderFieldsTooLarge = 431,
|
||||
UnavailableForLegalReasons = 451,
|
||||
InternalServerError = 500,
|
||||
NotImplemented = 501,
|
||||
BadGateway = 502,
|
||||
ServiceUnavailable = 503,
|
||||
GatewayTimeout = 504,
|
||||
HttpVersionNotSupported = 505,
|
||||
VariantAlsoNegotiates = 506,
|
||||
InsufficientStorage = 507,
|
||||
LoopDetected = 508,
|
||||
NotExtended = 510,
|
||||
NetworkAuthenticationRequired = 511,
|
||||
}
|
||||
|
||||
type UppercaseMethod =
|
||||
| 'GET'
|
||||
| 'DELETE'
|
||||
| 'HEAD'
|
||||
| 'OPTIONS'
|
||||
| 'POST'
|
||||
| 'PUT'
|
||||
| 'PATCH'
|
||||
| 'PURGE'
|
||||
| 'LINK'
|
||||
| 'UNLINK';
|
||||
|
||||
export type Method = (UppercaseMethod | Lowercase<UppercaseMethod>) & {};
|
||||
|
||||
export type ResponseType =
|
||||
| 'arraybuffer'
|
||||
| 'blob'
|
||||
| 'document'
|
||||
| 'json'
|
||||
| 'text'
|
||||
| 'stream'
|
||||
| 'formdata';
|
||||
|
||||
type UppercaseResponseEncoding =
|
||||
| 'ASCII'
|
||||
| 'ANSI'
|
||||
| 'BINARY'
|
||||
| 'BASE64'
|
||||
| 'BASE64URL'
|
||||
| 'HEX'
|
||||
| 'LATIN1'
|
||||
| 'UCS-2'
|
||||
| 'UCS2'
|
||||
| 'UTF-8'
|
||||
| 'UTF8'
|
||||
| 'UTF16LE';
|
||||
|
||||
export type responseEncoding = (
|
||||
| UppercaseResponseEncoding
|
||||
| Lowercase<UppercaseResponseEncoding>
|
||||
) & {};
|
||||
|
||||
export interface TransitionalOptions {
|
||||
silentJSONParsing?: boolean;
|
||||
forcedJSONParsing?: boolean;
|
||||
clarifyTimeoutError?: boolean;
|
||||
legacyInterceptorReqResOrdering?: boolean;
|
||||
}
|
||||
|
||||
export interface GenericAbortSignal {
|
||||
readonly aborted: boolean;
|
||||
onabort?: ((...args: any) => any) | null;
|
||||
addEventListener?: (...args: any) => any;
|
||||
removeEventListener?: (...args: any) => any;
|
||||
}
|
||||
|
||||
export interface FormDataVisitorHelpers {
|
||||
defaultVisitor: SerializerVisitor;
|
||||
convertValue: (value: any) => any;
|
||||
isVisitable: (value: any) => boolean;
|
||||
}
|
||||
|
||||
export interface SerializerVisitor {
|
||||
(
|
||||
this: GenericFormData,
|
||||
value: any,
|
||||
key: string | number,
|
||||
path: null | Array<string | number>,
|
||||
helpers: FormDataVisitorHelpers
|
||||
): boolean;
|
||||
}
|
||||
|
||||
export interface SerializerOptions {
|
||||
visitor?: SerializerVisitor;
|
||||
dots?: boolean;
|
||||
metaTokens?: boolean;
|
||||
indexes?: boolean | null;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line
|
||||
export interface FormSerializerOptions extends SerializerOptions {}
|
||||
|
||||
export interface ParamEncoder {
|
||||
(value: any, defaultEncoder: (value: any) => any): any;
|
||||
}
|
||||
|
||||
export interface CustomParamsSerializer {
|
||||
(params: Record<string, any>, options?: ParamsSerializerOptions): string;
|
||||
}
|
||||
|
||||
export interface ParamsSerializerOptions extends SerializerOptions {
|
||||
encode?: ParamEncoder;
|
||||
serialize?: CustomParamsSerializer;
|
||||
}
|
||||
|
||||
type MaxUploadRate = number;
|
||||
|
||||
type MaxDownloadRate = number;
|
||||
|
||||
type BrowserProgressEvent = any;
|
||||
|
||||
export interface AxiosProgressEvent {
|
||||
loaded: number;
|
||||
total?: number;
|
||||
progress?: number;
|
||||
bytes: number;
|
||||
rate?: number;
|
||||
estimated?: number;
|
||||
upload?: boolean;
|
||||
download?: boolean;
|
||||
event?: BrowserProgressEvent;
|
||||
lengthComputable: boolean;
|
||||
}
|
||||
|
||||
type Milliseconds = number;
|
||||
|
||||
type AxiosAdapterName = StringLiteralsOrString<'xhr' | 'http' | 'fetch'>;
|
||||
|
||||
type AxiosAdapterConfig = AxiosAdapter | AxiosAdapterName;
|
||||
|
||||
export type AddressFamily = 4 | 6 | undefined;
|
||||
|
||||
export interface LookupAddressEntry {
|
||||
address: string;
|
||||
family?: AddressFamily;
|
||||
}
|
||||
|
||||
export type LookupAddress = string | LookupAddressEntry;
|
||||
|
||||
export interface AxiosRequestConfig<D = any> {
|
||||
url?: string;
|
||||
method?: StringLiteralsOrString<Method>;
|
||||
baseURL?: string;
|
||||
allowAbsoluteUrls?: boolean;
|
||||
transformRequest?: AxiosRequestTransformer | AxiosRequestTransformer[];
|
||||
transformResponse?: AxiosResponseTransformer | AxiosResponseTransformer[];
|
||||
headers?: (RawAxiosRequestHeaders & MethodsHeaders) | AxiosHeaders;
|
||||
params?: any;
|
||||
paramsSerializer?: ParamsSerializerOptions | CustomParamsSerializer;
|
||||
data?: D;
|
||||
timeout?: Milliseconds;
|
||||
timeoutErrorMessage?: string;
|
||||
withCredentials?: boolean;
|
||||
adapter?: AxiosAdapterConfig | AxiosAdapterConfig[];
|
||||
auth?: AxiosBasicCredentials;
|
||||
responseType?: ResponseType;
|
||||
responseEncoding?: StringLiteralsOrString<responseEncoding>;
|
||||
xsrfCookieName?: string;
|
||||
xsrfHeaderName?: string;
|
||||
onUploadProgress?: (progressEvent: AxiosProgressEvent) => void;
|
||||
onDownloadProgress?: (progressEvent: AxiosProgressEvent) => void;
|
||||
maxContentLength?: number;
|
||||
validateStatus?: ((status: number) => boolean) | null;
|
||||
maxBodyLength?: number;
|
||||
maxRedirects?: number;
|
||||
maxRate?: number | [MaxUploadRate, MaxDownloadRate];
|
||||
beforeRedirect?: (
|
||||
options: Record<string, any>,
|
||||
responseDetails: {
|
||||
headers: Record<string, string>;
|
||||
statusCode: HttpStatusCode;
|
||||
}
|
||||
) => void;
|
||||
socketPath?: string | null;
|
||||
allowedSocketPaths?: string | string[] | null;
|
||||
transport?: any;
|
||||
httpAgent?: any;
|
||||
httpsAgent?: any;
|
||||
proxy?: AxiosProxyConfig | false;
|
||||
cancelToken?: CancelToken | undefined;
|
||||
decompress?: boolean;
|
||||
transitional?: TransitionalOptions;
|
||||
signal?: GenericAbortSignal;
|
||||
insecureHTTPParser?: boolean;
|
||||
env?: {
|
||||
FormData?: new (...args: any[]) => object;
|
||||
fetch?: (input: URL | Request | string, init?: RequestInit) => Promise<Response>;
|
||||
Request?: new (input: URL | Request | string, init?: RequestInit) => Request;
|
||||
Response?: new (
|
||||
body?: ArrayBuffer | ArrayBufferView | Blob | FormData | URLSearchParams | string | null,
|
||||
init?: ResponseInit
|
||||
) => Response;
|
||||
};
|
||||
formSerializer?: FormSerializerOptions;
|
||||
family?: AddressFamily;
|
||||
lookup?:
|
||||
| ((
|
||||
hostname: string,
|
||||
options: object,
|
||||
cb: (
|
||||
err: Error | null,
|
||||
address: LookupAddress | LookupAddress[],
|
||||
family?: AddressFamily
|
||||
) => void
|
||||
) => void)
|
||||
| ((
|
||||
hostname: string,
|
||||
options: object
|
||||
) => Promise<
|
||||
[address: LookupAddressEntry | LookupAddressEntry[], family?: AddressFamily] | LookupAddress
|
||||
>);
|
||||
withXSRFToken?: boolean | ((config: InternalAxiosRequestConfig) => boolean | undefined);
|
||||
parseReviver?: (this: any, key: string, value: any) => any;
|
||||
fetchOptions?: Omit<RequestInit, 'body' | 'headers' | 'method' | 'signal'> | Record<string, any>;
|
||||
httpVersion?: 1 | 2;
|
||||
http2Options?: Record<string, any> & {
|
||||
sessionTimeout?: number;
|
||||
};
|
||||
}
|
||||
|
||||
// Alias
|
||||
export type RawAxiosRequestConfig<D = any> = AxiosRequestConfig<D>;
|
||||
|
||||
export interface InternalAxiosRequestConfig<D = any> extends AxiosRequestConfig<D> {
|
||||
headers: AxiosRequestHeaders;
|
||||
}
|
||||
|
||||
export interface HeadersDefaults {
|
||||
common: RawAxiosRequestHeaders;
|
||||
delete: RawAxiosRequestHeaders;
|
||||
get: RawAxiosRequestHeaders;
|
||||
head: RawAxiosRequestHeaders;
|
||||
post: RawAxiosRequestHeaders;
|
||||
put: RawAxiosRequestHeaders;
|
||||
patch: RawAxiosRequestHeaders;
|
||||
options?: RawAxiosRequestHeaders;
|
||||
purge?: RawAxiosRequestHeaders;
|
||||
link?: RawAxiosRequestHeaders;
|
||||
unlink?: RawAxiosRequestHeaders;
|
||||
}
|
||||
|
||||
export interface AxiosDefaults<D = any> extends Omit<AxiosRequestConfig<D>, 'headers'> {
|
||||
headers: HeadersDefaults;
|
||||
}
|
||||
|
||||
export interface CreateAxiosDefaults<D = any> extends Omit<AxiosRequestConfig<D>, 'headers'> {
|
||||
headers?: RawAxiosRequestHeaders | AxiosHeaders | Partial<HeadersDefaults>;
|
||||
}
|
||||
|
||||
export interface AxiosResponse<T = any, D = any, H = {}> {
|
||||
data: T;
|
||||
status: number;
|
||||
statusText: string;
|
||||
headers: (H & RawAxiosResponseHeaders) | AxiosResponseHeaders;
|
||||
config: InternalAxiosRequestConfig<D>;
|
||||
request?: any;
|
||||
}
|
||||
|
||||
export class AxiosError<T = unknown, D = any> extends Error {
|
||||
constructor(
|
||||
message?: string,
|
||||
code?: string,
|
||||
config?: InternalAxiosRequestConfig<D>,
|
||||
request?: any,
|
||||
response?: AxiosResponse<T, D>
|
||||
);
|
||||
|
||||
config?: InternalAxiosRequestConfig<D>;
|
||||
code?: string;
|
||||
request?: any;
|
||||
response?: AxiosResponse<T, D>;
|
||||
isAxiosError: boolean;
|
||||
status?: number;
|
||||
toJSON: () => object;
|
||||
cause?: Error;
|
||||
event?: BrowserProgressEvent;
|
||||
static from<T = unknown, D = any>(
|
||||
error: Error | unknown,
|
||||
code?: string,
|
||||
config?: InternalAxiosRequestConfig<D>,
|
||||
request?: any,
|
||||
response?: AxiosResponse<T, D>,
|
||||
customProps?: object
|
||||
): AxiosError<T, D>;
|
||||
static readonly ERR_FR_TOO_MANY_REDIRECTS = 'ERR_FR_TOO_MANY_REDIRECTS';
|
||||
static readonly ERR_BAD_OPTION_VALUE = 'ERR_BAD_OPTION_VALUE';
|
||||
static readonly ERR_BAD_OPTION = 'ERR_BAD_OPTION';
|
||||
static readonly ERR_NETWORK = 'ERR_NETWORK';
|
||||
static readonly ERR_DEPRECATED = 'ERR_DEPRECATED';
|
||||
static readonly ERR_BAD_RESPONSE = 'ERR_BAD_RESPONSE';
|
||||
static readonly ERR_BAD_REQUEST = 'ERR_BAD_REQUEST';
|
||||
static readonly ERR_NOT_SUPPORT = 'ERR_NOT_SUPPORT';
|
||||
static readonly ERR_INVALID_URL = 'ERR_INVALID_URL';
|
||||
static readonly ERR_CANCELED = 'ERR_CANCELED';
|
||||
static readonly ERR_FORM_DATA_DEPTH_EXCEEDED = 'ERR_FORM_DATA_DEPTH_EXCEEDED';
|
||||
static readonly ECONNABORTED = 'ECONNABORTED';
|
||||
static readonly ETIMEDOUT = 'ETIMEDOUT';
|
||||
}
|
||||
|
||||
export class CanceledError<T> extends AxiosError<T> {
|
||||
readonly name: 'CanceledError';
|
||||
}
|
||||
|
||||
export type AxiosPromise<T = any> = Promise<AxiosResponse<T>>;
|
||||
|
||||
export interface CancelStatic {
|
||||
new (message?: string): Cancel;
|
||||
}
|
||||
|
||||
export interface Cancel {
|
||||
message: string | undefined;
|
||||
}
|
||||
|
||||
export interface Canceler {
|
||||
(message?: string, config?: AxiosRequestConfig, request?: any): void;
|
||||
}
|
||||
|
||||
export interface CancelTokenStatic {
|
||||
new (executor: (cancel: Canceler) => void): CancelToken;
|
||||
source(): CancelTokenSource;
|
||||
}
|
||||
|
||||
export interface CancelToken {
|
||||
promise: Promise<Cancel>;
|
||||
reason?: Cancel;
|
||||
throwIfRequested(): void;
|
||||
}
|
||||
|
||||
export interface CancelTokenSource {
|
||||
token: CancelToken;
|
||||
cancel: Canceler;
|
||||
}
|
||||
|
||||
export interface AxiosInterceptorOptions {
|
||||
synchronous?: boolean;
|
||||
runWhen?: ((config: InternalAxiosRequestConfig) => boolean) | null;
|
||||
}
|
||||
|
||||
type AxiosInterceptorFulfilled<T> = (value: T) => T | Promise<T>;
|
||||
type AxiosInterceptorRejected = (error: any) => any;
|
||||
|
||||
type AxiosRequestInterceptorUse<T> = (
|
||||
onFulfilled?: AxiosInterceptorFulfilled<T> | null,
|
||||
onRejected?: AxiosInterceptorRejected | null,
|
||||
options?: AxiosInterceptorOptions
|
||||
) => number;
|
||||
|
||||
type AxiosResponseInterceptorUse<T> = (
|
||||
onFulfilled?: AxiosInterceptorFulfilled<T> | null,
|
||||
onRejected?: AxiosInterceptorRejected | null
|
||||
) => number;
|
||||
|
||||
interface AxiosInterceptorHandler<T> {
|
||||
fulfilled: AxiosInterceptorFulfilled<T>;
|
||||
rejected?: AxiosInterceptorRejected;
|
||||
synchronous: boolean;
|
||||
runWhen?: ((config: InternalAxiosRequestConfig) => boolean) | null;
|
||||
}
|
||||
|
||||
export interface AxiosInterceptorManager<V> {
|
||||
use: V extends AxiosResponse ? AxiosResponseInterceptorUse<V> : AxiosRequestInterceptorUse<V>;
|
||||
eject(id: number): void;
|
||||
clear(): void;
|
||||
handlers?: Array<AxiosInterceptorHandler<V>>;
|
||||
}
|
||||
|
||||
export class Axios {
|
||||
constructor(config?: AxiosRequestConfig);
|
||||
defaults: AxiosDefaults;
|
||||
interceptors: {
|
||||
request: AxiosInterceptorManager<InternalAxiosRequestConfig>;
|
||||
response: AxiosInterceptorManager<AxiosResponse>;
|
||||
};
|
||||
getUri(config?: AxiosRequestConfig): string;
|
||||
request<T = any, R = AxiosResponse<T>, D = any>(config: AxiosRequestConfig<D>): Promise<R>;
|
||||
get<T = any, R = AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
config?: AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
delete<T = any, R = AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
config?: AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
head<T = any, R = AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
config?: AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
options<T = any, R = AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
config?: AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
post<T = any, R = AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
data?: D,
|
||||
config?: AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
put<T = any, R = AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
data?: D,
|
||||
config?: AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
patch<T = any, R = AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
data?: D,
|
||||
config?: AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
postForm<T = any, R = AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
data?: D,
|
||||
config?: AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
putForm<T = any, R = AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
data?: D,
|
||||
config?: AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
patchForm<T = any, R = AxiosResponse<T>, D = any>(
|
||||
url: string,
|
||||
data?: D,
|
||||
config?: AxiosRequestConfig<D>
|
||||
): Promise<R>;
|
||||
}
|
||||
|
||||
export interface AxiosInstance extends Axios {
|
||||
<T = any, R = AxiosResponse<T>, D = any>(config: AxiosRequestConfig<D>): Promise<R>;
|
||||
<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
|
||||
|
||||
create(config?: CreateAxiosDefaults): AxiosInstance;
|
||||
defaults: Omit<AxiosDefaults, 'headers'> & {
|
||||
headers: HeadersDefaults & {
|
||||
[key: string]: AxiosHeaderValue;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export interface GenericFormData {
|
||||
append(name: string, value: any, options?: any): any;
|
||||
}
|
||||
|
||||
export interface GenericHTMLFormElement {
|
||||
name: string;
|
||||
method: string;
|
||||
submit(): void;
|
||||
}
|
||||
|
||||
export function getAdapter(
|
||||
adapters: AxiosAdapterConfig | AxiosAdapterConfig[] | undefined
|
||||
): AxiosAdapter;
|
||||
|
||||
export function toFormData(
|
||||
sourceObj: object,
|
||||
targetFormData?: GenericFormData,
|
||||
options?: FormSerializerOptions
|
||||
): GenericFormData;
|
||||
|
||||
export function formToJSON(form: GenericFormData | GenericHTMLFormElement): object;
|
||||
|
||||
export function isAxiosError<T = any, D = any>(payload: any): payload is AxiosError<T, D>;
|
||||
|
||||
export function spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R;
|
||||
|
||||
export function isCancel<T = any>(value: any): value is CanceledError<T>;
|
||||
|
||||
export function all<T>(values: Array<T | Promise<T>>): Promise<T[]>;
|
||||
|
||||
export function mergeConfig<D = any>(
|
||||
config1: AxiosRequestConfig<D>,
|
||||
config2: AxiosRequestConfig<D>
|
||||
): AxiosRequestConfig<D>;
|
||||
|
||||
export interface AxiosStatic extends AxiosInstance {
|
||||
Cancel: CancelStatic;
|
||||
CancelToken: CancelTokenStatic;
|
||||
Axios: typeof Axios;
|
||||
AxiosError: typeof AxiosError;
|
||||
HttpStatusCode: typeof HttpStatusCode;
|
||||
readonly VERSION: string;
|
||||
isCancel: typeof isCancel;
|
||||
all: typeof all;
|
||||
spread: typeof spread;
|
||||
isAxiosError: typeof isAxiosError;
|
||||
toFormData: typeof toFormData;
|
||||
formToJSON: typeof formToJSON;
|
||||
getAdapter: typeof getAdapter;
|
||||
CanceledError: typeof CanceledError;
|
||||
AxiosHeaders: typeof AxiosHeaders;
|
||||
mergeConfig: typeof mergeConfig;
|
||||
}
|
||||
|
||||
declare const axios: AxiosStatic;
|
||||
|
||||
export default axios;
|
||||
43
.claude/skills/教学日程查询/node_modules/axios/index.js
generated
vendored
Normal file
43
.claude/skills/教学日程查询/node_modules/axios/index.js
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
import axios from './lib/axios.js';
|
||||
|
||||
// This module is intended to unwrap Axios default export as named.
|
||||
// Keep top-level export same with static properties
|
||||
// so that it can keep same with es module or cjs
|
||||
const {
|
||||
Axios,
|
||||
AxiosError,
|
||||
CanceledError,
|
||||
isCancel,
|
||||
CancelToken,
|
||||
VERSION,
|
||||
all,
|
||||
Cancel,
|
||||
isAxiosError,
|
||||
spread,
|
||||
toFormData,
|
||||
AxiosHeaders,
|
||||
HttpStatusCode,
|
||||
formToJSON,
|
||||
getAdapter,
|
||||
mergeConfig,
|
||||
} = axios;
|
||||
|
||||
export {
|
||||
axios as default,
|
||||
Axios,
|
||||
AxiosError,
|
||||
CanceledError,
|
||||
isCancel,
|
||||
CancelToken,
|
||||
VERSION,
|
||||
all,
|
||||
Cancel,
|
||||
isAxiosError,
|
||||
spread,
|
||||
toFormData,
|
||||
AxiosHeaders,
|
||||
HttpStatusCode,
|
||||
formToJSON,
|
||||
getAdapter,
|
||||
mergeConfig,
|
||||
};
|
||||
36
.claude/skills/教学日程查询/node_modules/axios/lib/adapters/README.md
generated
vendored
Normal file
36
.claude/skills/教学日程查询/node_modules/axios/lib/adapters/README.md
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
# axios // adapters
|
||||
|
||||
The modules under `adapters/` are modules that handle dispatching a request and settling a returned `Promise` once a response is received.
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
var settle = require('../core/settle');
|
||||
|
||||
module.exports = function myAdapter(config) {
|
||||
// At this point:
|
||||
// - config has been merged with defaults
|
||||
// - request transformers have already run
|
||||
// - request interceptors have already run
|
||||
|
||||
// Make the request using config provided
|
||||
// Upon response settle the Promise
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
var response = {
|
||||
data: responseData,
|
||||
status: request.status,
|
||||
statusText: request.statusText,
|
||||
headers: responseHeaders,
|
||||
config: config,
|
||||
request: request,
|
||||
};
|
||||
|
||||
settle(resolve, reject, response);
|
||||
|
||||
// From here:
|
||||
// - response transformers will run
|
||||
// - response interceptors will run
|
||||
});
|
||||
};
|
||||
```
|
||||
130
.claude/skills/教学日程查询/node_modules/axios/lib/adapters/adapters.js
generated
vendored
Normal file
130
.claude/skills/教学日程查询/node_modules/axios/lib/adapters/adapters.js
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
import utils from '../utils.js';
|
||||
import httpAdapter from './http.js';
|
||||
import xhrAdapter from './xhr.js';
|
||||
import * as fetchAdapter from './fetch.js';
|
||||
import AxiosError from '../core/AxiosError.js';
|
||||
|
||||
/**
|
||||
* Known adapters mapping.
|
||||
* Provides environment-specific adapters for Axios:
|
||||
* - `http` for Node.js
|
||||
* - `xhr` for browsers
|
||||
* - `fetch` for fetch API-based requests
|
||||
*
|
||||
* @type {Object<string, Function|Object>}
|
||||
*/
|
||||
const knownAdapters = {
|
||||
http: httpAdapter,
|
||||
xhr: xhrAdapter,
|
||||
fetch: {
|
||||
get: fetchAdapter.getFetch,
|
||||
},
|
||||
};
|
||||
|
||||
// Assign adapter names for easier debugging and identification
|
||||
utils.forEach(knownAdapters, (fn, value) => {
|
||||
if (fn) {
|
||||
try {
|
||||
Object.defineProperty(fn, 'name', { value });
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-empty
|
||||
}
|
||||
Object.defineProperty(fn, 'adapterName', { value });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Render a rejection reason string for unknown or unsupported adapters
|
||||
*
|
||||
* @param {string} reason
|
||||
* @returns {string}
|
||||
*/
|
||||
const renderReason = (reason) => `- ${reason}`;
|
||||
|
||||
/**
|
||||
* Check if the adapter is resolved (function, null, or false)
|
||||
*
|
||||
* @param {Function|null|false} adapter
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isResolvedHandle = (adapter) =>
|
||||
utils.isFunction(adapter) || adapter === null || adapter === false;
|
||||
|
||||
/**
|
||||
* Get the first suitable adapter from the provided list.
|
||||
* Tries each adapter in order until a supported one is found.
|
||||
* Throws an AxiosError if no adapter is suitable.
|
||||
*
|
||||
* @param {Array<string|Function>|string|Function} adapters - Adapter(s) by name or function.
|
||||
* @param {Object} config - Axios request configuration
|
||||
* @throws {AxiosError} If no suitable adapter is available
|
||||
* @returns {Function} The resolved adapter function
|
||||
*/
|
||||
function getAdapter(adapters, config) {
|
||||
adapters = utils.isArray(adapters) ? adapters : [adapters];
|
||||
|
||||
const { length } = adapters;
|
||||
let nameOrAdapter;
|
||||
let adapter;
|
||||
|
||||
const rejectedReasons = {};
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
nameOrAdapter = adapters[i];
|
||||
let id;
|
||||
|
||||
adapter = nameOrAdapter;
|
||||
|
||||
if (!isResolvedHandle(nameOrAdapter)) {
|
||||
adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];
|
||||
|
||||
if (adapter === undefined) {
|
||||
throw new AxiosError(`Unknown adapter '${id}'`);
|
||||
}
|
||||
}
|
||||
|
||||
if (adapter && (utils.isFunction(adapter) || (adapter = adapter.get(config)))) {
|
||||
break;
|
||||
}
|
||||
|
||||
rejectedReasons[id || '#' + i] = adapter;
|
||||
}
|
||||
|
||||
if (!adapter) {
|
||||
const reasons = Object.entries(rejectedReasons).map(
|
||||
([id, state]) =>
|
||||
`adapter ${id} ` +
|
||||
(state === false ? 'is not supported by the environment' : 'is not available in the build')
|
||||
);
|
||||
|
||||
let s = length
|
||||
? reasons.length > 1
|
||||
? 'since :\n' + reasons.map(renderReason).join('\n')
|
||||
: ' ' + renderReason(reasons[0])
|
||||
: 'as no adapter specified';
|
||||
|
||||
throw new AxiosError(
|
||||
`There is no suitable adapter to dispatch the request ` + s,
|
||||
'ERR_NOT_SUPPORT'
|
||||
);
|
||||
}
|
||||
|
||||
return adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports Axios adapters and utility to resolve an adapter
|
||||
*/
|
||||
export default {
|
||||
/**
|
||||
* Resolve an adapter from a list of adapter names or functions.
|
||||
* @type {Function}
|
||||
*/
|
||||
getAdapter,
|
||||
|
||||
/**
|
||||
* Exposes all known adapters
|
||||
* @type {Object<string, Function|Object>}
|
||||
*/
|
||||
adapters: knownAdapters,
|
||||
};
|
||||
353
.claude/skills/教学日程查询/node_modules/axios/lib/adapters/fetch.js
generated
vendored
Normal file
353
.claude/skills/教学日程查询/node_modules/axios/lib/adapters/fetch.js
generated
vendored
Normal file
@@ -0,0 +1,353 @@
|
||||
import platform from '../platform/index.js';
|
||||
import utils from '../utils.js';
|
||||
import AxiosError from '../core/AxiosError.js';
|
||||
import composeSignals from '../helpers/composeSignals.js';
|
||||
import { trackStream } from '../helpers/trackStream.js';
|
||||
import AxiosHeaders from '../core/AxiosHeaders.js';
|
||||
import {
|
||||
progressEventReducer,
|
||||
progressEventDecorator,
|
||||
asyncDecorator,
|
||||
} from '../helpers/progressEventReducer.js';
|
||||
import resolveConfig from '../helpers/resolveConfig.js';
|
||||
import settle from '../core/settle.js';
|
||||
|
||||
const DEFAULT_CHUNK_SIZE = 64 * 1024;
|
||||
|
||||
const { isFunction } = utils;
|
||||
|
||||
const globalFetchAPI = (({ Request, Response }) => ({
|
||||
Request,
|
||||
Response,
|
||||
}))(utils.global);
|
||||
|
||||
const { ReadableStream, TextEncoder } = utils.global;
|
||||
|
||||
const test = (fn, ...args) => {
|
||||
try {
|
||||
return !!fn(...args);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const factory = (env) => {
|
||||
env = utils.merge.call(
|
||||
{
|
||||
skipUndefined: true,
|
||||
},
|
||||
globalFetchAPI,
|
||||
env
|
||||
);
|
||||
|
||||
const { fetch: envFetch, Request, Response } = env;
|
||||
const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function';
|
||||
const isRequestSupported = isFunction(Request);
|
||||
const isResponseSupported = isFunction(Response);
|
||||
|
||||
if (!isFetchSupported) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream);
|
||||
|
||||
const encodeText =
|
||||
isFetchSupported &&
|
||||
(typeof TextEncoder === 'function'
|
||||
? (
|
||||
(encoder) => (str) =>
|
||||
encoder.encode(str)
|
||||
)(new TextEncoder())
|
||||
: async (str) => new Uint8Array(await new Request(str).arrayBuffer()));
|
||||
|
||||
const supportsRequestStream =
|
||||
isRequestSupported &&
|
||||
isReadableStreamSupported &&
|
||||
test(() => {
|
||||
let duplexAccessed = false;
|
||||
|
||||
const request = new Request(platform.origin, {
|
||||
body: new ReadableStream(),
|
||||
method: 'POST',
|
||||
get duplex() {
|
||||
duplexAccessed = true;
|
||||
return 'half';
|
||||
},
|
||||
});
|
||||
|
||||
const hasContentType = request.headers.has('Content-Type');
|
||||
|
||||
if (request.body != null) {
|
||||
request.body.cancel();
|
||||
}
|
||||
|
||||
return duplexAccessed && !hasContentType;
|
||||
});
|
||||
|
||||
const supportsResponseStream =
|
||||
isResponseSupported &&
|
||||
isReadableStreamSupported &&
|
||||
test(() => utils.isReadableStream(new Response('').body));
|
||||
|
||||
const resolvers = {
|
||||
stream: supportsResponseStream && ((res) => res.body),
|
||||
};
|
||||
|
||||
isFetchSupported &&
|
||||
(() => {
|
||||
['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach((type) => {
|
||||
!resolvers[type] &&
|
||||
(resolvers[type] = (res, config) => {
|
||||
let method = res && res[type];
|
||||
|
||||
if (method) {
|
||||
return method.call(res);
|
||||
}
|
||||
|
||||
throw new AxiosError(
|
||||
`Response type '${type}' is not supported`,
|
||||
AxiosError.ERR_NOT_SUPPORT,
|
||||
config
|
||||
);
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
const getBodyLength = async (body) => {
|
||||
if (body == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (utils.isBlob(body)) {
|
||||
return body.size;
|
||||
}
|
||||
|
||||
if (utils.isSpecCompliantForm(body)) {
|
||||
const _request = new Request(platform.origin, {
|
||||
method: 'POST',
|
||||
body,
|
||||
});
|
||||
return (await _request.arrayBuffer()).byteLength;
|
||||
}
|
||||
|
||||
if (utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) {
|
||||
return body.byteLength;
|
||||
}
|
||||
|
||||
if (utils.isURLSearchParams(body)) {
|
||||
body = body + '';
|
||||
}
|
||||
|
||||
if (utils.isString(body)) {
|
||||
return (await encodeText(body)).byteLength;
|
||||
}
|
||||
};
|
||||
|
||||
const resolveBodyLength = async (headers, body) => {
|
||||
const length = utils.toFiniteNumber(headers.getContentLength());
|
||||
|
||||
return length == null ? getBodyLength(body) : length;
|
||||
};
|
||||
|
||||
return async (config) => {
|
||||
let {
|
||||
url,
|
||||
method,
|
||||
data,
|
||||
signal,
|
||||
cancelToken,
|
||||
timeout,
|
||||
onDownloadProgress,
|
||||
onUploadProgress,
|
||||
responseType,
|
||||
headers,
|
||||
withCredentials = 'same-origin',
|
||||
fetchOptions,
|
||||
} = resolveConfig(config);
|
||||
|
||||
let _fetch = envFetch || fetch;
|
||||
|
||||
responseType = responseType ? (responseType + '').toLowerCase() : 'text';
|
||||
|
||||
let composedSignal = composeSignals(
|
||||
[signal, cancelToken && cancelToken.toAbortSignal()],
|
||||
timeout
|
||||
);
|
||||
|
||||
let request = null;
|
||||
|
||||
const unsubscribe =
|
||||
composedSignal &&
|
||||
composedSignal.unsubscribe &&
|
||||
(() => {
|
||||
composedSignal.unsubscribe();
|
||||
});
|
||||
|
||||
let requestContentLength;
|
||||
|
||||
try {
|
||||
if (
|
||||
onUploadProgress &&
|
||||
supportsRequestStream &&
|
||||
method !== 'get' &&
|
||||
method !== 'head' &&
|
||||
(requestContentLength = await resolveBodyLength(headers, data)) !== 0
|
||||
) {
|
||||
let _request = new Request(url, {
|
||||
method: 'POST',
|
||||
body: data,
|
||||
duplex: 'half',
|
||||
});
|
||||
|
||||
let contentTypeHeader;
|
||||
|
||||
if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {
|
||||
headers.setContentType(contentTypeHeader);
|
||||
}
|
||||
|
||||
if (_request.body) {
|
||||
const [onProgress, flush] = progressEventDecorator(
|
||||
requestContentLength,
|
||||
progressEventReducer(asyncDecorator(onUploadProgress))
|
||||
);
|
||||
|
||||
data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);
|
||||
}
|
||||
}
|
||||
|
||||
if (!utils.isString(withCredentials)) {
|
||||
withCredentials = withCredentials ? 'include' : 'omit';
|
||||
}
|
||||
|
||||
// Cloudflare Workers throws when credentials are defined
|
||||
// see https://github.com/cloudflare/workerd/issues/902
|
||||
const isCredentialsSupported = isRequestSupported && 'credentials' in Request.prototype;
|
||||
|
||||
// If data is FormData and Content-Type is multipart/form-data without boundary,
|
||||
// delete it so fetch can set it correctly with the boundary
|
||||
if (utils.isFormData(data)) {
|
||||
const contentType = headers.getContentType();
|
||||
if (
|
||||
contentType &&
|
||||
/^multipart\/form-data/i.test(contentType) &&
|
||||
!/boundary=/i.test(contentType)
|
||||
) {
|
||||
headers.delete('content-type');
|
||||
}
|
||||
}
|
||||
|
||||
const resolvedOptions = {
|
||||
...fetchOptions,
|
||||
signal: composedSignal,
|
||||
method: method.toUpperCase(),
|
||||
headers: headers.normalize().toJSON(),
|
||||
body: data,
|
||||
duplex: 'half',
|
||||
credentials: isCredentialsSupported ? withCredentials : undefined,
|
||||
};
|
||||
|
||||
request = isRequestSupported && new Request(url, resolvedOptions);
|
||||
|
||||
let response = await (isRequestSupported
|
||||
? _fetch(request, fetchOptions)
|
||||
: _fetch(url, resolvedOptions));
|
||||
|
||||
const isStreamResponse =
|
||||
supportsResponseStream && (responseType === 'stream' || responseType === 'response');
|
||||
|
||||
if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) {
|
||||
const options = {};
|
||||
|
||||
['status', 'statusText', 'headers'].forEach((prop) => {
|
||||
options[prop] = response[prop];
|
||||
});
|
||||
|
||||
const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length'));
|
||||
|
||||
const [onProgress, flush] =
|
||||
(onDownloadProgress &&
|
||||
progressEventDecorator(
|
||||
responseContentLength,
|
||||
progressEventReducer(asyncDecorator(onDownloadProgress), true)
|
||||
)) ||
|
||||
[];
|
||||
|
||||
response = new Response(
|
||||
trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {
|
||||
flush && flush();
|
||||
unsubscribe && unsubscribe();
|
||||
}),
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
responseType = responseType || 'text';
|
||||
|
||||
let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text'](
|
||||
response,
|
||||
config
|
||||
);
|
||||
|
||||
!isStreamResponse && unsubscribe && unsubscribe();
|
||||
|
||||
return await new Promise((resolve, reject) => {
|
||||
settle(resolve, reject, {
|
||||
data: responseData,
|
||||
headers: AxiosHeaders.from(response.headers),
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
config,
|
||||
request,
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
unsubscribe && unsubscribe();
|
||||
|
||||
if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {
|
||||
throw Object.assign(
|
||||
new AxiosError(
|
||||
'Network Error',
|
||||
AxiosError.ERR_NETWORK,
|
||||
config,
|
||||
request,
|
||||
err && err.response
|
||||
),
|
||||
{
|
||||
cause: err.cause || err,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
throw AxiosError.from(err, err && err.code, config, request, err && err.response);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const seedCache = new Map();
|
||||
|
||||
export const getFetch = (config) => {
|
||||
let env = (config && config.env) || {};
|
||||
const { fetch, Request, Response } = env;
|
||||
const seeds = [Request, Response, fetch];
|
||||
|
||||
let len = seeds.length,
|
||||
i = len,
|
||||
seed,
|
||||
target,
|
||||
map = seedCache;
|
||||
|
||||
while (i--) {
|
||||
seed = seeds[i];
|
||||
target = map.get(seed);
|
||||
|
||||
target === undefined && map.set(seed, (target = i ? new Map() : factory(env)));
|
||||
|
||||
map = target;
|
||||
}
|
||||
|
||||
return target;
|
||||
};
|
||||
|
||||
const adapter = getFetch();
|
||||
|
||||
export default adapter;
|
||||
1083
.claude/skills/教学日程查询/node_modules/axios/lib/adapters/http.js
generated
vendored
Normal file
1083
.claude/skills/教学日程查询/node_modules/axios/lib/adapters/http.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
222
.claude/skills/教学日程查询/node_modules/axios/lib/adapters/xhr.js
generated
vendored
Normal file
222
.claude/skills/教学日程查询/node_modules/axios/lib/adapters/xhr.js
generated
vendored
Normal file
@@ -0,0 +1,222 @@
|
||||
import utils from '../utils.js';
|
||||
import settle from '../core/settle.js';
|
||||
import transitionalDefaults from '../defaults/transitional.js';
|
||||
import AxiosError from '../core/AxiosError.js';
|
||||
import CanceledError from '../cancel/CanceledError.js';
|
||||
import parseProtocol from '../helpers/parseProtocol.js';
|
||||
import platform from '../platform/index.js';
|
||||
import AxiosHeaders from '../core/AxiosHeaders.js';
|
||||
import { progressEventReducer } from '../helpers/progressEventReducer.js';
|
||||
import resolveConfig from '../helpers/resolveConfig.js';
|
||||
|
||||
const isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';
|
||||
|
||||
export default isXHRAdapterSupported &&
|
||||
function (config) {
|
||||
return new Promise(function dispatchXhrRequest(resolve, reject) {
|
||||
const _config = resolveConfig(config);
|
||||
let requestData = _config.data;
|
||||
const requestHeaders = AxiosHeaders.from(_config.headers).normalize();
|
||||
let { responseType, onUploadProgress, onDownloadProgress } = _config;
|
||||
let onCanceled;
|
||||
let uploadThrottled, downloadThrottled;
|
||||
let flushUpload, flushDownload;
|
||||
|
||||
function done() {
|
||||
flushUpload && flushUpload(); // flush events
|
||||
flushDownload && flushDownload(); // flush events
|
||||
|
||||
_config.cancelToken && _config.cancelToken.unsubscribe(onCanceled);
|
||||
|
||||
_config.signal && _config.signal.removeEventListener('abort', onCanceled);
|
||||
}
|
||||
|
||||
let request = new XMLHttpRequest();
|
||||
|
||||
request.open(_config.method.toUpperCase(), _config.url, true);
|
||||
|
||||
// Set the request timeout in MS
|
||||
request.timeout = _config.timeout;
|
||||
|
||||
function onloadend() {
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
// Prepare the response
|
||||
const responseHeaders = AxiosHeaders.from(
|
||||
'getAllResponseHeaders' in request && request.getAllResponseHeaders()
|
||||
);
|
||||
const responseData =
|
||||
!responseType || responseType === 'text' || responseType === 'json'
|
||||
? request.responseText
|
||||
: request.response;
|
||||
const response = {
|
||||
data: responseData,
|
||||
status: request.status,
|
||||
statusText: request.statusText,
|
||||
headers: responseHeaders,
|
||||
config,
|
||||
request,
|
||||
};
|
||||
|
||||
settle(
|
||||
function _resolve(value) {
|
||||
resolve(value);
|
||||
done();
|
||||
},
|
||||
function _reject(err) {
|
||||
reject(err);
|
||||
done();
|
||||
},
|
||||
response
|
||||
);
|
||||
|
||||
// Clean up request
|
||||
request = null;
|
||||
}
|
||||
|
||||
if ('onloadend' in request) {
|
||||
// Use onloadend if available
|
||||
request.onloadend = onloadend;
|
||||
} else {
|
||||
// Listen for ready state to emulate onloadend
|
||||
request.onreadystatechange = function handleLoad() {
|
||||
if (!request || request.readyState !== 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The request errored out and we didn't get a response, this will be
|
||||
// handled by onerror instead
|
||||
// With one exception: request that using file: protocol, most browsers
|
||||
// will return status as 0 even though it's a successful request
|
||||
if (
|
||||
request.status === 0 &&
|
||||
!(request.responseURL && request.responseURL.indexOf('file:') === 0)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
// readystate handler is calling before onerror or ontimeout handlers,
|
||||
// so we should call onloadend on the next 'tick'
|
||||
setTimeout(onloadend);
|
||||
};
|
||||
}
|
||||
|
||||
// Handle browser request cancellation (as opposed to a manual cancellation)
|
||||
request.onabort = function handleAbort() {
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request));
|
||||
|
||||
// Clean up request
|
||||
request = null;
|
||||
};
|
||||
|
||||
// Handle low level network errors
|
||||
request.onerror = function handleError(event) {
|
||||
// Browsers deliver a ProgressEvent in XHR onerror
|
||||
// (message may be empty; when present, surface it)
|
||||
// See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event
|
||||
const msg = event && event.message ? event.message : 'Network Error';
|
||||
const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request);
|
||||
// attach the underlying event for consumers who want details
|
||||
err.event = event || null;
|
||||
reject(err);
|
||||
request = null;
|
||||
};
|
||||
|
||||
// Handle timeout
|
||||
request.ontimeout = function handleTimeout() {
|
||||
let timeoutErrorMessage = _config.timeout
|
||||
? 'timeout of ' + _config.timeout + 'ms exceeded'
|
||||
: 'timeout exceeded';
|
||||
const transitional = _config.transitional || transitionalDefaults;
|
||||
if (_config.timeoutErrorMessage) {
|
||||
timeoutErrorMessage = _config.timeoutErrorMessage;
|
||||
}
|
||||
reject(
|
||||
new AxiosError(
|
||||
timeoutErrorMessage,
|
||||
transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,
|
||||
config,
|
||||
request
|
||||
)
|
||||
);
|
||||
|
||||
// Clean up request
|
||||
request = null;
|
||||
};
|
||||
|
||||
// Remove Content-Type if data is undefined
|
||||
requestData === undefined && requestHeaders.setContentType(null);
|
||||
|
||||
// Add headers to the request
|
||||
if ('setRequestHeader' in request) {
|
||||
utils.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) {
|
||||
request.setRequestHeader(key, val);
|
||||
});
|
||||
}
|
||||
|
||||
// Add withCredentials to request if needed
|
||||
if (!utils.isUndefined(_config.withCredentials)) {
|
||||
request.withCredentials = !!_config.withCredentials;
|
||||
}
|
||||
|
||||
// Add responseType to request if needed
|
||||
if (responseType && responseType !== 'json') {
|
||||
request.responseType = _config.responseType;
|
||||
}
|
||||
|
||||
// Handle progress if needed
|
||||
if (onDownloadProgress) {
|
||||
[downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true);
|
||||
request.addEventListener('progress', downloadThrottled);
|
||||
}
|
||||
|
||||
// Not all browsers support upload events
|
||||
if (onUploadProgress && request.upload) {
|
||||
[uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress);
|
||||
|
||||
request.upload.addEventListener('progress', uploadThrottled);
|
||||
|
||||
request.upload.addEventListener('loadend', flushUpload);
|
||||
}
|
||||
|
||||
if (_config.cancelToken || _config.signal) {
|
||||
// Handle cancellation
|
||||
// eslint-disable-next-line func-names
|
||||
onCanceled = (cancel) => {
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel);
|
||||
request.abort();
|
||||
request = null;
|
||||
};
|
||||
|
||||
_config.cancelToken && _config.cancelToken.subscribe(onCanceled);
|
||||
if (_config.signal) {
|
||||
_config.signal.aborted
|
||||
? onCanceled()
|
||||
: _config.signal.addEventListener('abort', onCanceled);
|
||||
}
|
||||
}
|
||||
|
||||
const protocol = parseProtocol(_config.url);
|
||||
|
||||
if (protocol && platform.protocols.indexOf(protocol) === -1) {
|
||||
reject(
|
||||
new AxiosError(
|
||||
'Unsupported protocol ' + protocol + ':',
|
||||
AxiosError.ERR_BAD_REQUEST,
|
||||
config
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the request
|
||||
request.send(requestData || null);
|
||||
});
|
||||
};
|
||||
89
.claude/skills/教学日程查询/node_modules/axios/lib/axios.js
generated
vendored
Normal file
89
.claude/skills/教学日程查询/node_modules/axios/lib/axios.js
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
'use strict';
|
||||
|
||||
import utils from './utils.js';
|
||||
import bind from './helpers/bind.js';
|
||||
import Axios from './core/Axios.js';
|
||||
import mergeConfig from './core/mergeConfig.js';
|
||||
import defaults from './defaults/index.js';
|
||||
import formDataToJSON from './helpers/formDataToJSON.js';
|
||||
import CanceledError from './cancel/CanceledError.js';
|
||||
import CancelToken from './cancel/CancelToken.js';
|
||||
import isCancel from './cancel/isCancel.js';
|
||||
import { VERSION } from './env/data.js';
|
||||
import toFormData from './helpers/toFormData.js';
|
||||
import AxiosError from './core/AxiosError.js';
|
||||
import spread from './helpers/spread.js';
|
||||
import isAxiosError from './helpers/isAxiosError.js';
|
||||
import AxiosHeaders from './core/AxiosHeaders.js';
|
||||
import adapters from './adapters/adapters.js';
|
||||
import HttpStatusCode from './helpers/HttpStatusCode.js';
|
||||
|
||||
/**
|
||||
* Create an instance of Axios
|
||||
*
|
||||
* @param {Object} defaultConfig The default config for the instance
|
||||
*
|
||||
* @returns {Axios} A new instance of Axios
|
||||
*/
|
||||
function createInstance(defaultConfig) {
|
||||
const context = new Axios(defaultConfig);
|
||||
const instance = bind(Axios.prototype.request, context);
|
||||
|
||||
// Copy axios.prototype to instance
|
||||
utils.extend(instance, Axios.prototype, context, { allOwnKeys: true });
|
||||
|
||||
// Copy context to instance
|
||||
utils.extend(instance, context, null, { allOwnKeys: true });
|
||||
|
||||
// Factory for creating new instances
|
||||
instance.create = function create(instanceConfig) {
|
||||
return createInstance(mergeConfig(defaultConfig, instanceConfig));
|
||||
};
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
// Create the default instance to be exported
|
||||
const axios = createInstance(defaults);
|
||||
|
||||
// Expose Axios class to allow class inheritance
|
||||
axios.Axios = Axios;
|
||||
|
||||
// Expose Cancel & CancelToken
|
||||
axios.CanceledError = CanceledError;
|
||||
axios.CancelToken = CancelToken;
|
||||
axios.isCancel = isCancel;
|
||||
axios.VERSION = VERSION;
|
||||
axios.toFormData = toFormData;
|
||||
|
||||
// Expose AxiosError class
|
||||
axios.AxiosError = AxiosError;
|
||||
|
||||
// alias for CanceledError for backward compatibility
|
||||
axios.Cancel = axios.CanceledError;
|
||||
|
||||
// Expose all/spread
|
||||
axios.all = function all(promises) {
|
||||
return Promise.all(promises);
|
||||
};
|
||||
|
||||
axios.spread = spread;
|
||||
|
||||
// Expose isAxiosError
|
||||
axios.isAxiosError = isAxiosError;
|
||||
|
||||
// Expose mergeConfig
|
||||
axios.mergeConfig = mergeConfig;
|
||||
|
||||
axios.AxiosHeaders = AxiosHeaders;
|
||||
|
||||
axios.formToJSON = (thing) => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);
|
||||
|
||||
axios.getAdapter = adapters.getAdapter;
|
||||
|
||||
axios.HttpStatusCode = HttpStatusCode;
|
||||
|
||||
axios.default = axios;
|
||||
|
||||
// this module should only have a default export
|
||||
export default axios;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user