diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 00000000..786f8d98 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,73 @@ +kind: pipeline +type: docker +name: Build and Deploy + +clone: + depth: 10 + +volumes: + - name: go_cache + host: + path: /data/drone_cache/go_cache + +steps: + - name: restore-cache + image: drillster/drone-volume-cache + volumes: + - name: go_cache + path: /cache + settings: + restore: true + mount: + - ./.npm-cache + - ./node_modules + + - name: build + image: node:alpine + pull: if-not-exists + commands: + - export NODE_OPTIONS=--max_old_space_size=6144 + - echo ${DRONE_BRANCH} + - echo ${DRONE_TAG} + - echo ${DRONE_COMMIT} + - echo ${DRONE_COMMIT:0-7} + - npm config set registry https://registry.npmmirror.com + - npm install -g pnpm + - pnpm config set registry https://registry.npmmirror.com + - pnpm i + - pnpm build + + - name: rebuild-cache + image: drillster/drone-volume-cache + volumes: + - name: go_cache + path: /cache + settings: + rebuild: true + mount: + - ./.npm-cache + - ./node_modules + + - name: scp files + image: appleboy/drone-scp + pull: if-not-exists + settings: + host: + from_secret: HOST + username: + from_secret: USERNAME + password: + from_secret: PASSWORD + port: + from_secret: PORT + target: + from_secret: TARGET_PATH + source: dist/* + overwrite: true + rm: true + +trigger: + branch: + - master + event: + - push diff --git a/.gitee/workflows/linter.yml b/.gitee/workflows/linter.yml deleted file mode 100644 index 450ec865..00000000 --- a/.gitee/workflows/linter.yml +++ /dev/null @@ -1,30 +0,0 @@ ---- -name: Lint Code - -permissions: - contents: write - -on: - pull_request: - branches: [main] - -jobs: - lint: - name: Lint All Code - runs-on: ubuntu-latest - - steps: - - name: Checkout Code - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Lint Code Base - uses: github/super-linter@v4 - env: - VALIDATE_ALL_CODEBASE: false - DEFAULT_BRANCH: main - # To change branch master or main - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - FILTER_REGEX_EXCLUDE: (docs|.github) - VALIDATE_MARKDOWN: false diff --git a/.gitee/workflows/release.yml b/.gitee/workflows/release.yml deleted file mode 100644 index 0bf7c92d..00000000 --- a/.gitee/workflows/release.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Release - -permissions: - contents: write - -on: - push: - tags: - - "v*" - -jobs: - release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - uses: actions/setup-node@v3 - with: - node-version: 18.x - - - run: npx githublogen - env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000..d2d3368f --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,43 @@ +name: Build and Deploy + +on: + push: + branches: [ "master" ] + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10.x + run_install: false + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install + + - name: Build project + run: pnpm build + + - name: Upload via SCP + uses: appleboy/scp-action@v1 + with: + host: ${{ secrets.SSH_HOST }} + username: ${{ secrets.SSH_USERNAME }} + password: ${{ secrets.SSH_PASSWORD }} + port: ${{ secrets.SSH_PORT }} + source: "dist/*" + target: ${{ secrets.TARGET_PATH }} + rm: true + overwrite: true diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 450ec865..a11ed3c9 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -6,7 +6,7 @@ permissions: on: pull_request: - branches: [main] + branches: [master] jobs: lint: @@ -23,7 +23,7 @@ jobs: uses: github/super-linter@v4 env: VALIDATE_ALL_CODEBASE: false - DEFAULT_BRANCH: main + DEFAULT_BRANCH: master # To change branch master or main GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} FILTER_REGEX_EXCLUDE: (docs|.github) diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..a292c36d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,13 @@ +# 更新日志 + +## [v1.0.0](https://gitee.com/xlsea/ruoyi-plus-soybean/releases/tag/v1.0.0) (2025-06-05) + +### 🚀 新功能 + +1.0.0 版本正式发布,此版本不包含工作流与多语言,请期待后续版本发布。 + +### ❤️ 贡献者 + +首次发版不展示过多贡献者,敬请谅解 + +[](https://github.com/honghuangdc) [](https://gitee.com/xlsea) [](https://gitee.com/elio-an) [](https://github.com/wangqiqi95) diff --git a/README.md b/README.md index 9b669db4..05152803 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@
一个基于 RuoYi-Vue-Plus 的后端能力和 Soybean Admin 前端特性的现代化多租户管理系统
-
+
+
@@ -346,13 +347,14 @@ console.log(t('common.confirm'));
- **邮箱**: xlsea@linux.do
- **作者主页**: https://gitee.com/xlsea
+
- **作者**: Elio
- **邮箱**: 1983933789@qq.com
- **作者主页**: https://gitee.com/ahcode
## 💬 交流群
-
+
## 🧧 捐献作者
diff --git a/docs/sql/sys_menu.sql b/docs/sql/sys_menu.sql
index c1608184..a04de6d6 100644
--- a/docs/sql/sys_menu.sql
+++ b/docs/sql/sys_menu.sql
@@ -26,9 +26,13 @@ UPDATE `sys_menu` SET `icon` = 'carbon:operations-record' WHERE `menu_id` = 500;
UPDATE `sys_menu` SET `icon` = 'tabler:login-2' WHERE `menu_id` = 501;
UPDATE `sys_menu` SET `icon` = 'gg:debug' WHERE `menu_id` = 1500;
UPDATE `sys_menu` SET `icon` = 'gg:debug' WHERE `menu_id` = 1506;
+UPDATE `sys_menu` SET `path` = 'oss/config', `component` = 'system/oss-config/index', `icon` = 'hugeicons:configuration-01' WHERE `menu_id` = 133;
-- IFrame 类型
UPDATE `sys_menu` SET `component` = 'FrameView', `query_param` = 'https://ruoyi.xlsea.cn/admin/', `is_frame` = 2, `icon` = 'bx:bxl-spring-boot' WHERE `menu_id` = 117;
UPDATE `sys_menu` SET `component` = 'FrameView', `query_param` = 'https://preview.snailjob.opensnail.com/', `is_frame` = 2, `icon` = 'gridicons:scheduled' WHERE `menu_id` = 120;
-- 外链类型
UPDATE `sys_menu` SET `path` = 'https://gitee.com/xlsea/ruoyi-plus-soybean', `component` = 'FrameView', `icon` = 'local-icon-gitee' WHERE `menu_id` = 4;
+
+-- plus-ui 需要禁用的页面
+UPDATE `sys_menu` SET `status` = '1' WHERE `menu_id` IN ( '116', '130', '131', '132', '11700', '11701' );
diff --git a/docs/template/index-tree.vue.vm b/docs/template/index-tree.vue.vm
index 0ab2b7b7..cf6ebed6 100644
--- a/docs/template/index-tree.vue.vm
+++ b/docs/template/index-tree.vue.vm
@@ -56,12 +56,6 @@ const {
align: 'center',
width: 48
},
- {
- key: 'index',
- title: $t('common.index'),
- align: 'center',
- width: 64
- },
#foreach ($column in $columns)
#if($column.list)
{
diff --git a/package.json b/package.json
index fecc7bba..d044bea0 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "ruoyi-vue-plus",
"type": "module",
- "version": "1.0.0-beta.1",
+ "version": "1.0.0",
"description": "RuoYi-Vue-Plus多租户管理系统",
"author": {
"name": "xlsea",
diff --git a/packages/hooks/src/use-count-down.ts b/packages/hooks/src/use-count-down.ts
index bfad064b..4f95b731 100644
--- a/packages/hooks/src/use-count-down.ts
+++ b/packages/hooks/src/use-count-down.ts
@@ -2,40 +2,59 @@ import { computed, onScopeDispose, ref } from 'vue';
import { useRafFn } from '@vueuse/core';
/**
- * count down
+ * A hook for implementing a countdown timer. It uses `requestAnimationFrame` for smooth and accurate timing,
+ * independent of the screen refresh rate.
*
- * @param seconds - count down seconds
+ * @param initialSeconds - The total number of seconds for the countdown.
*/
-export default function useCountDown(seconds: number) {
- const FPS_PER_SECOND = 60;
+export default function useCountDown(initialSeconds: number) {
+ const remainingSeconds = ref(0);
- const fps = ref(0);
+ const count = computed(() => Math.ceil(remainingSeconds.value));
- const count = computed(() => Math.ceil(fps.value / FPS_PER_SECOND));
-
- const isCounting = computed(() => fps.value > 0);
+ const isCounting = computed(() => remainingSeconds.value > 0);
const { pause, resume } = useRafFn(
- () => {
- if (fps.value > 0) {
- fps.value -= 1;
- } else {
+ ({ delta }) => {
+ // delta: milliseconds elapsed since the last frame.
+
+ // If countdown already reached zero or below, ensure it's 0 and stop.
+ if (remainingSeconds.value <= 0) {
+ remainingSeconds.value = 0;
+ pause();
+ return;
+ }
+
+ // Calculate seconds passed since the last frame.
+ const secondsPassed = delta / 1000;
+ remainingSeconds.value -= secondsPassed;
+
+ // If countdown has finished after decrementing.
+ if (remainingSeconds.value <= 0) {
+ remainingSeconds.value = 0;
pause();
}
},
- { immediate: false }
+ { immediate: false } // The timer does not start automatically.
);
- function start(updateSeconds: number = seconds) {
- fps.value = FPS_PER_SECOND * updateSeconds;
+ /**
+ * Starts the countdown.
+ *
+ * @param [updatedSeconds=initialSeconds] - Optionally, start with a new duration. Default is `initialSeconds`
+ */
+ function start(updatedSeconds: number = initialSeconds) {
+ remainingSeconds.value = updatedSeconds;
resume();
}
+ /** Stops the countdown and resets the remaining time to 0. */
function stop() {
- fps.value = 0;
+ remainingSeconds.value = 0;
pause();
}
+ // Ensure the rAF loop is cleaned up when the component is unmounted.
onScopeDispose(() => {
pause();
});
diff --git a/src/assets/svg-icon/bell.svg b/src/assets/svg-icon/bell.svg
new file mode 100644
index 00000000..bffd0ce6
--- /dev/null
+++ b/src/assets/svg-icon/bell.svg
@@ -0,0 +1 @@
+
diff --git a/src/components/common/data-table.vue b/src/components/common/data-table.vue
new file mode 100644
index 00000000..cc5ce083
--- /dev/null
+++ b/src/components/common/data-table.vue
@@ -0,0 +1,35 @@
+
+
+
+