dvc890 commited on
Commit
a7ede54
·
verified ·
1 Parent(s): a2e8f5c

Upload 27 files

Browse files
Files changed (4) hide show
  1. index.css +14 -0
  2. index.tsx +2 -0
  3. pages/UserList.tsx +3 -2
  4. server.js +40 -24
index.css ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ @tailwind base;
3
+ @tailwind components;
4
+ @tailwind utilities;
5
+
6
+ body {
7
+ margin: 0;
8
+ font-family: 'Noto Sans SC', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
9
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
10
+ sans-serif;
11
+ -webkit-font-smoothing: antialiased;
12
+ -moz-osx-font-smoothing: grayscale;
13
+ background-color: #f9fafb;
14
+ }
index.tsx CHANGED
@@ -1,6 +1,8 @@
 
1
  import React from 'react';
2
  import ReactDOM from 'react-dom/client';
3
  import App from './App';
 
4
 
5
  const rootElement = document.getElementById('root');
6
  if (!rootElement) {
 
1
+
2
  import React from 'react';
3
  import ReactDOM from 'react-dom/client';
4
  import App from './App';
5
+ import './index.css';
6
 
7
  const rootElement = document.getElementById('root');
8
  if (!rootElement) {
pages/UserList.tsx CHANGED
@@ -1,3 +1,4 @@
 
1
  import React, { useState, useEffect } from 'react';
2
  import { User, UserRole, UserStatus, School } from '../types';
3
  import { api } from '../services/api';
@@ -80,7 +81,7 @@ export const UserList: React.FC = () => {
80
  </thead>
81
  <tbody className="divide-y divide-gray-100">
82
  {users.map(user => {
83
- const isSelf = !!(currentUser && (user._id === currentUser._id || user.username === currentUser.username));
84
  return (
85
  <tr key={user._id || user.id} className="hover:bg-gray-50">
86
  <td className="px-4 py-3">
@@ -163,4 +164,4 @@ export const UserList: React.FC = () => {
163
  </div>
164
  </div>
165
  );
166
- };
 
1
+
2
  import React, { useState, useEffect } from 'react';
3
  import { User, UserRole, UserStatus, School } from '../types';
4
  import { api } from '../services/api';
 
81
  </thead>
82
  <tbody className="divide-y divide-gray-100">
83
  {users.map(user => {
84
+ const isSelf = currentUser && (user._id === currentUser._id || user.username === currentUser.username);
85
  return (
86
  <tr key={user._id || user.id} className="hover:bg-gray-50">
87
  <td className="px-4 py-3">
 
164
  </div>
165
  </div>
166
  );
167
+ };
server.js CHANGED
@@ -157,21 +157,29 @@ const ConfigModel = mongoose.model('Config', ConfigSchema);
157
  const initData = async () => {
158
  if (InMemoryDB.isFallback) return;
159
  try {
160
- // 1. Create Default School if none
161
- const schoolCount = await School.countDocuments();
162
- let defaultSchool;
163
- if (schoolCount === 0) {
 
 
 
 
 
 
 
 
 
 
 
164
  defaultSchool = await School.create({ name: '第一实验小学', code: 'EXP01' });
165
- console.log('Initialized Default School');
166
- } else {
167
- defaultSchool = await School.findOne();
168
  }
169
 
170
- // 2. Create Admin
171
- const userCount = await User.countDocuments();
172
- if (userCount === 0) {
173
- await User.create([
174
- {
175
  username: 'admin',
176
  password: 'admin',
177
  role: 'ADMIN',
@@ -179,22 +187,30 @@ const initData = async () => {
179
  schoolId: defaultSchool._id.toString(),
180
  trueName: '超级管理员',
181
  email: 'admin@system.com'
182
- }
183
- ]);
184
  }
185
 
186
- // 3. Create Default Subjects for this school
187
- const subjCount = await SubjectModel.countDocuments({ schoolId: defaultSchool._id.toString() });
188
- if (subjCount === 0) {
189
- await SubjectModel.create([
190
- { schoolId: defaultSchool._id.toString(), name: '语文', code: 'CHI', color: '#ef4444', excellenceThreshold: 90 },
191
- { schoolId: defaultSchool._id.toString(), name: '数学', code: 'MAT', color: '#3b82f6', excellenceThreshold: 90 },
192
- { schoolId: defaultSchool._id.toString(), name: '英语', code: 'ENG', color: '#f59e0b', excellenceThreshold: 90 },
193
- { schoolId: defaultSchool._id.toString(), name: '科学', code: 'SCI', color: '#10b981', excellenceThreshold: 85 }
194
- ]);
 
 
 
 
 
 
195
  }
 
 
196
  } catch (err) {
197
- console.error('Init Data Error', err);
198
  }
199
  };
200
  mongoose.connection.once('open', initData);
 
157
  const initData = async () => {
158
  if (InMemoryDB.isFallback) return;
159
  try {
160
+ console.log('🔄 Checking database initialization...');
161
+
162
+ // --- FIX: Drop Legacy Indexes ---
163
+ // In multi-tenancy, 'name' on subjects should NOT be unique globally.
164
+ // We try to drop the index 'name_1' if it exists.
165
+ try {
166
+ await mongoose.connection.collection('subjects').dropIndex('name_1');
167
+ console.log('⚠️ Dropped legacy unique index on subjects collection to support multi-school subjects.');
168
+ } catch (e) {
169
+ // Index might not exist or error code 27 (index not found), ignore
170
+ }
171
+
172
+ // 1. Create Default School (Upsert)
173
+ let defaultSchool = await School.findOne({ code: 'EXP01' });
174
+ if (!defaultSchool) {
175
  defaultSchool = await School.create({ name: '第一实验小学', code: 'EXP01' });
176
+ console.log('Initialized Default School');
 
 
177
  }
178
 
179
+ // 2. Create Admin (Upsert)
180
+ const adminExists = await User.findOne({ username: 'admin' });
181
+ if (!adminExists) {
182
+ await User.create({
 
183
  username: 'admin',
184
  password: 'admin',
185
  role: 'ADMIN',
 
187
  schoolId: defaultSchool._id.toString(),
188
  trueName: '超级管理员',
189
  email: 'admin@system.com'
190
+ });
191
+ console.log('✅ Initialized Admin User');
192
  }
193
 
194
+ // 3. Create Default Subjects (Upsert)
195
+ // Use updateOne with upsert to prevent E11000 errors if run multiple times
196
+ const defaultSubjects = [
197
+ { schoolId: defaultSchool._id.toString(), name: '语文', code: 'CHI', color: '#ef4444', excellenceThreshold: 90 },
198
+ { schoolId: defaultSchool._id.toString(), name: '数学', code: 'MAT', color: '#3b82f6', excellenceThreshold: 90 },
199
+ { schoolId: defaultSchool._id.toString(), name: '英语', code: 'ENG', color: '#f59e0b', excellenceThreshold: 90 },
200
+ { schoolId: defaultSchool._id.toString(), name: '科学', code: 'SCI', color: '#10b981', excellenceThreshold: 85 }
201
+ ];
202
+
203
+ for (const sub of defaultSubjects) {
204
+ await SubjectModel.updateOne(
205
+ { schoolId: sub.schoolId, name: sub.name }, // Check if subject exists for this school
206
+ { $set: sub },
207
+ { upsert: true }
208
+ );
209
  }
210
+ console.log('✅ Initialized/Updated Default Subjects');
211
+
212
  } catch (err) {
213
+ console.error('Init Data Error', err);
214
  }
215
  };
216
  mongoose.connection.once('open', initData);