zhangjie 1 gadu atpakaļ
vecāks
revīzija
bcab0adee6

+ 10 - 0
electron/db/createdb.ts

@@ -0,0 +1,10 @@
+import sequelize from './sequelizeInstance';
+import './models/trackTask';
+import './models/trackTaskDetail';
+
+async function createDb() {
+  await sequelize.sync({ force: true });
+  console.log('All models were synchronized successfully.');
+}
+
+export default createDb;

+ 52 - 0
electron/db/modelApi/trackTask.ts

@@ -0,0 +1,52 @@
+import { Op } from 'sequelize';
+
+import TrackTask, { TrackTaskCreationAttributes } from '../models/trackTask';
+import TrackTeskDetail, {
+  TrackTaskDetailCreationAttributes,
+} from '../models/trackTaskDetail';
+import sequelize from '../sequelizeInstance';
+
+export async function getUnfinishTrackTask() {
+  const task = await TrackTask.findOne({
+    where: { status: 0 },
+  }).catch((err) => {
+    console.dir(err);
+  });
+  return task ? task.dataValues : null;
+}
+
+export async function createTrackTask(
+  data: TrackTaskCreationAttributes,
+  details: TrackTaskDetailCreationAttributes[]
+) {
+  const t = await sequelize.transaction();
+
+  try {
+    await TrackTask.update(
+      {
+        status: 2,
+      },
+      {
+        where: {
+          status: { [Op.or]: [0, 1] },
+        },
+        transaction: t,
+      }
+    );
+
+    // 保存任务
+    const task = await TrackTask.create(data, { transaction: t });
+
+    details.forEach((item) => {
+      item.trackTaskId = task.id;
+    });
+    await TrackTeskDetail.bulkCreate(details, { transaction: t });
+
+    await t.commit();
+
+    return task.dataValues;
+  } catch (error) {
+    await t.rollback();
+    return Promise.reject(error);
+  }
+}

+ 70 - 0
electron/db/models/trackTask.ts

@@ -0,0 +1,70 @@
+import {
+  Model,
+  DataTypes,
+  CreationOptional,
+  InferAttributes,
+  InferCreationAttributes,
+} from 'sequelize';
+import sequelize from '../sequelizeInstance';
+
+class TrackTask extends Model<
+  // eslint-disable-next-line no-use-before-define
+  InferAttributes<TrackTask>,
+  // eslint-disable-next-line no-use-before-define
+  InferCreationAttributes<TrackTask>
+> {
+  declare id: CreationOptional<number>;
+
+  declare schoolId: string;
+
+  declare semesterId: string;
+
+  declare examId: string;
+
+  declare pathRule: string;
+
+  declare status: number;
+}
+
+TrackTask.init(
+  {
+    id: {
+      type: DataTypes.INTEGER.UNSIGNED,
+      autoIncrement: true,
+      primaryKey: true,
+    },
+    schoolId: {
+      type: DataTypes.STRING,
+      allowNull: false,
+    },
+    semesterId: {
+      type: DataTypes.STRING,
+      allowNull: false,
+    },
+    examId: {
+      type: DataTypes.STRING,
+      allowNull: false,
+    },
+    pathRule: {
+      type: DataTypes.STRING,
+      allowNull: false,
+      comment: '保存路径规则',
+    },
+    status: {
+      type: DataTypes.INTEGER,
+      allowNull: false,
+      defaultValue: 0,
+      // 任务状态:0:未开始,1:运行中,2:已完成
+    },
+  },
+  {
+    sequelize,
+    modelName: 'TrackTask',
+    underscored: true,
+    tableName: 'trackTask',
+  }
+);
+
+export type TrackTaskCreationAttributes = InferCreationAttributes<TrackTask>;
+
+export default TrackTask;

+ 87 - 0
electron/db/models/trackTaskDetail.ts

@@ -0,0 +1,87 @@
+import {
+  Model,
+  DataTypes,
+  CreationOptional,
+  InferAttributes,
+  InferCreationAttributes,
+} from 'sequelize';
+import sequelize from '../sequelizeInstance';
+import TrackTask from './trackTask';
+
+class TrackTaskDetail extends Model<
+  // eslint-disable-next-line no-use-before-define
+  InferAttributes<TrackTaskDetail>,
+  // eslint-disable-next-line no-use-before-define
+  InferCreationAttributes<TrackTaskDetail>
+> {
+  declare id: CreationOptional<number>;
+
+  declare trackTaskId: number;
+
+  declare studentName: string;
+
+  declare studentCode: string;
+
+  declare courseName: string;
+
+  declare courseCode: string;
+
+  declare status: number;
+
+  declare error: string | null;
+}
+
+TrackTaskDetail.init(
+  {
+    id: {
+      type: DataTypes.INTEGER.UNSIGNED,
+      autoIncrement: true,
+      primaryKey: true,
+    },
+    trackTaskId: {
+      type: DataTypes.INTEGER.UNSIGNED,
+      allowNull: false,
+    },
+    studentName: {
+      type: DataTypes.STRING,
+      allowNull: false,
+    },
+    studentCode: {
+      type: DataTypes.STRING,
+      allowNull: false,
+    },
+    courseName: {
+      type: DataTypes.STRING,
+      allowNull: false,
+    },
+    courseCode: {
+      type: DataTypes.STRING,
+      allowNull: false,
+    },
+    status: {
+      type: DataTypes.INTEGER,
+      allowNull: false,
+      defaultValue: 0,
+      // 任务状态:0:未开始,1:运行中,2:已完成
+    },
+    error: {
+      type: DataTypes.TEXT,
+      allowNull: true,
+      comment: '错误信息',
+    },
+  },
+  {
+    sequelize,
+    modelName: 'TrackTaskDetail',
+    underscored: true,
+    tableName: 'trackTaskDetail',
+  }
+);
+
+TrackTask.hasMany(TrackTaskDetail);
+TrackTaskDetail.belongsTo(TrackTask);
+
+export type TrackTaskDetailCreationAttributes =
+  InferCreationAttributes<TrackTaskDetail>;
+
+export default TrackTaskDetail;

+ 21 - 0
electron/db/sequelizeInstance.ts

@@ -0,0 +1,21 @@
+import { Sequelize } from 'sequelize';
+import { getDatabasePath } from '../preload/utils';
+
+// doc: https://sequelize.org/docs/v6/getting-started/
+
+const logging = () => {};
+// const logging =
+//   process.env.NODE_ENV === "production" ? () => {} : (msg) => console.log(msg);
+
+const sequelize = new Sequelize({
+  dialect: 'sqlite',
+  storage: getDatabasePath(),
+  logging,
+  pool: {
+    max: 20,
+    min: 5,
+    acquire: 100000,
+  },
+});
+
+export default sequelize;

+ 15 - 0
electron/preload/apiDb.ts

@@ -0,0 +1,15 @@
+import {
+  getUnfinishTrackTask,
+  createTrackTask,
+} from '../db/modelApi/trackTask';
+import createDb from '../db/createdb';
+
+const dbApi = {
+  getUnfinishTrackTask,
+  createTrackTask,
+  createDb,
+};
+
+export type DbApi = typeof dbApi;
+
+export default dbApi;

+ 2 - 0
electron/preload/index.d.ts

@@ -1,9 +1,11 @@
 import type { ElectronApi } from './apiElectron';
+import type { DbApi } from './apiDb';
 import type { CommonApi } from './api';
 
 declare global {
   interface Window {
     electron: ElectronApi;
+    db: DbApi;
     api: CommonApi;
   }
 }

+ 4 - 0
electron/preload/index.ts

@@ -1,5 +1,6 @@
 import { contextBridge } from 'electron';
 import electronApi from './apiElectron';
+import dbApi from './apiDb';
 import api from './api';
 
 // Use `contextBridge` APIs to expose Electron APIs to
@@ -8,6 +9,7 @@ import api from './api';
 if (process.contextIsolated) {
   try {
     contextBridge.exposeInMainWorld('electron', electronApi);
+    contextBridge.exposeInMainWorld('db', dbApi);
     contextBridge.exposeInMainWorld('api', api);
   } catch (error) {
     console.error(error);
@@ -16,5 +18,7 @@ if (process.contextIsolated) {
   // @ts-ignore (define in dts)
   window.electron = electronApi;
   // @ts-ignore (define in dts)
+  window.db = dbApi;
+  // @ts-ignore (define in dts)
   window.api = api;
 }

+ 17 - 4
electron/preload/utils.ts

@@ -1,18 +1,31 @@
 import fs from 'node:fs';
 import path from 'node:path';
 
+const STORE_PATH_NAME = 'store';
 const TEMP_PATH_NAME = 'temp';
 
-console.log(__dirname);
-
 export function getResourcesDir() {
+  return process.env.NODE_ENV === 'development'
+    ? path.join(__dirname, '../../resources/')
+    : path.join(__dirname, '../../../app.asar.unpacked/resources/');
+}
+
+export function getRootDir() {
   return process.env.NODE_ENV === 'development'
     ? path.join(__dirname, '../../')
-    : path.join(__dirname, './app.asar.unpacked/');
+    : path.join(__dirname, '../../../../');
+}
+
+export function getDatabasePath() {
+  return path.join(getRootDir(), 'database', 'database.sqlite');
+}
+
+export function getStoreDir() {
+  return path.join(getRootDir(), STORE_PATH_NAME);
 }
 
 export function getTempPath() {
-  return path.join(__dirname, TEMP_PATH_NAME);
+  return path.join(getStoreDir(), TEMP_PATH_NAME);
 }
 
 export function getImagicPath() {

+ 3 - 1
package.json

@@ -19,7 +19,7 @@
     "postinstall": "electron-builder install-app-deps",
     "build": "npm run typecheck && electron-vite build",
     "build:unpack": "npm run build && electron-builder --dir",
-    "build:win": "npm run build && electron-builder --win",
+    "build:win": "npm run build && electron-builder --win --x64",
     "build:mac": "npm run build && electron-builder --mac",
     "build:linux": "npm run build && electron-builder --linux"
   },
@@ -53,6 +53,8 @@
     "pinia": "^2.0.23",
     "pinia-plugin-persistedstate": "^3.2.1",
     "query-string": "^8.0.3",
+    "sequelize": "^6.37.3",
+    "sqlite3": "^5.1.6",
     "vue": "^3.2.40",
     "vue-ls": "^4.2.0",
     "vue-router": "^4.0.14"

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 483 - 36
pnpm-lock.yaml


+ 2 - 0
src/main.ts

@@ -12,6 +12,8 @@ import App from './App.vue';
 import '@/assets/styles/index.less';
 import '@/api/interceptor';
 
+// await window.db.createDb();
+
 const app = createApp(App);
 
 app.use(ArcoVue, {});

+ 2 - 2
src/router/index.ts

@@ -1,4 +1,4 @@
-import { createRouter, createWebHistory } from 'vue-router';
+import { createRouter, createWebHashHistory } from 'vue-router';
 import NProgress from 'nprogress'; // progress bar
 import 'nprogress/nprogress.css';
 
@@ -9,7 +9,7 @@ import createRouteGuard from './guard';
 NProgress.configure({ showSpinner: false }); // NProgress Configuration
 
 const router = createRouter({
-  history: createWebHistory(),
+  history: createWebHashHistory(),
   routes: [
     {
       path: '/',

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels