Compare commits
No commits in common. "develop" and "master" have entirely different histories.
@ -1,106 +0,0 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const { execSync } = require('child_process')
|
||||
|
||||
const scopes = fs
|
||||
.readdirSync(path.resolve(__dirname, 'src'), { withFileTypes: true })
|
||||
.filter((dirent) => dirent.isDirectory())
|
||||
.map((dirent) => dirent.name.replace(/s$/, ''))
|
||||
|
||||
// precomputed scope
|
||||
const scopeComplete = execSync('git status --porcelain || true')
|
||||
.toString()
|
||||
.trim()
|
||||
.split('\n')
|
||||
.find((r) => ~r.indexOf('M src'))
|
||||
?.replace(/(\/)/g, '%%')
|
||||
?.match(/src%%((\w|-)*)/)?.[1]
|
||||
?.replace(/s$/, '')
|
||||
|
||||
module.exports = {
|
||||
ignores: [(commit) => commit.includes('init')],
|
||||
extends: ['@commitlint/config-conventional'],
|
||||
rules: {
|
||||
'body-leading-blank': [2, 'always'],
|
||||
'footer-leading-blank': [1, 'always'],
|
||||
'header-max-length': [2, 'always', 108],
|
||||
'subject-empty': [2, 'never'],
|
||||
'type-empty': [2, 'never'],
|
||||
'subject-case': [0],
|
||||
'type-enum': [
|
||||
2,
|
||||
'always',
|
||||
[
|
||||
'feat',
|
||||
'fix',
|
||||
'perf',
|
||||
'style',
|
||||
'docs',
|
||||
'test',
|
||||
'refactor',
|
||||
'build',
|
||||
'ci',
|
||||
'chore',
|
||||
'revert',
|
||||
'wip',
|
||||
'workflow',
|
||||
'types',
|
||||
'release',
|
||||
],
|
||||
],
|
||||
},
|
||||
prompt: {
|
||||
/** @use `pnpm commit :f` */
|
||||
alias: {
|
||||
f: 'docs: fix typos',
|
||||
r: 'docs: update README',
|
||||
s: 'style: update code format',
|
||||
b: 'build: bump dependencies',
|
||||
c: 'chore: update config',
|
||||
},
|
||||
customScopesAlign: !scopeComplete ? 'top' : 'bottom',
|
||||
defaultScope: scopeComplete,
|
||||
scopes: [...scopes, 'mock'],
|
||||
allowEmptyIssuePrefixs: false,
|
||||
allowCustomIssuePrefixs: false,
|
||||
|
||||
// English
|
||||
typesAppend: [
|
||||
{ value: 'wip', name: 'wip: work in process' },
|
||||
{ value: 'workflow', name: 'workflow: workflow improvements' },
|
||||
{ value: 'types', name: 'types: type definition file changes' },
|
||||
],
|
||||
|
||||
// 中英文对照版
|
||||
// messages: {
|
||||
// type: '选择你要提交的类型 :',
|
||||
// scope: '选择一个提交范围 (可选):',
|
||||
// customScope: '请输入自定义的提交范围 :',
|
||||
// subject: '填写简短精炼的变更描述 :\n',
|
||||
// body: '填写更加详细的变更描述 (可选)。使用 "|" 换行 :\n',
|
||||
// breaking: '列举非兼容性重大的变更 (可选)。使用 "|" 换行 :\n',
|
||||
// footerPrefixsSelect: '选择关联issue前缀 (可选):',
|
||||
// customFooterPrefixs: '输入自定义issue前缀 :',
|
||||
// footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
|
||||
// confirmCommit: '是否提交或修改commit ?',
|
||||
// },
|
||||
// types: [
|
||||
// { value: 'feat', name: 'feat: 新增功能' },
|
||||
// { value: 'fix', name: 'fix: 修复缺陷' },
|
||||
// { value: 'docs', name: 'docs: 文档变更' },
|
||||
// { value: 'style', name: 'style: 代码格式' },
|
||||
// { value: 'refactor', name: 'refactor: 代码重构' },
|
||||
// { value: 'perf', name: 'perf: 性能优化' },
|
||||
// { value: 'test', name: 'test: 添加疏漏测试或已有测试改动' },
|
||||
// { value: 'build', name: 'build: 构建流程、外部依赖变更 (如升级 npm 包、修改打包配置等)' },
|
||||
// { value: 'ci', name: 'ci: 修改 CI 配置、脚本' },
|
||||
// { value: 'revert', name: 'revert: 回滚 commit' },
|
||||
// { value: 'chore', name: 'chore: 对构建过程或辅助工具和库的更改 (不影响源文件、测试用例)' },
|
||||
// { value: 'wip', name: 'wip: 正在开发中' },
|
||||
// { value: 'workflow', name: 'workflow: 工作流程改进' },
|
||||
// { value: 'types', name: 'types: 类型定义文件修改' },
|
||||
// ],
|
||||
// emptyScopesAlias: 'empty: 不填写',
|
||||
// customScopesAlias: 'custom: 自定义',
|
||||
},
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
root = true
|
||||
|
||||
[*] # 表示所有文件适用
|
||||
charset = utf-8 # 设置文件字符集为 utf-8
|
||||
indent_style = space # 缩进风格(tab | space)
|
||||
indent_size = 2 # 缩进大小
|
||||
end_of_line = lf # 控制换行类型(lf | cr | crlf)
|
||||
trim_trailing_whitespace = true # 去除行首的任意空白字符
|
||||
insert_final_newline = true # 始终在文件末尾插入一个新行
|
||||
|
||||
[*.md] # 表示仅 md 文件适用以下规则
|
||||
max_line_length = off # 关闭最大行长度限制
|
||||
trim_trailing_whitespace = false # 关闭末尾空格修剪
|
||||
@ -1 +0,0 @@
|
||||
src/uni_modules/
|
||||
@ -1,100 +0,0 @@
|
||||
{
|
||||
"globals": {
|
||||
"Component": true,
|
||||
"ComponentPublicInstance": true,
|
||||
"ComputedRef": true,
|
||||
"DirectiveBinding": true,
|
||||
"EffectScope": true,
|
||||
"ExtractDefaultPropTypes": true,
|
||||
"ExtractPropTypes": true,
|
||||
"ExtractPublicPropTypes": true,
|
||||
"InjectionKey": true,
|
||||
"MaybeRef": true,
|
||||
"MaybeRefOrGetter": true,
|
||||
"PropType": true,
|
||||
"Ref": true,
|
||||
"VNode": true,
|
||||
"WritableComputedRef": true,
|
||||
"computed": true,
|
||||
"createApp": true,
|
||||
"customRef": true,
|
||||
"defineAsyncComponent": true,
|
||||
"defineComponent": true,
|
||||
"effectScope": true,
|
||||
"getCurrentInstance": true,
|
||||
"getCurrentScope": true,
|
||||
"h": true,
|
||||
"inject": true,
|
||||
"isProxy": true,
|
||||
"isReactive": true,
|
||||
"isReadonly": true,
|
||||
"isRef": true,
|
||||
"markRaw": true,
|
||||
"nextTick": true,
|
||||
"onActivated": true,
|
||||
"onAddToFavorites": true,
|
||||
"onBackPress": true,
|
||||
"onBeforeMount": true,
|
||||
"onBeforeUnmount": true,
|
||||
"onBeforeUpdate": true,
|
||||
"onDeactivated": true,
|
||||
"onError": true,
|
||||
"onErrorCaptured": true,
|
||||
"onHide": true,
|
||||
"onLaunch": true,
|
||||
"onLoad": true,
|
||||
"onMounted": true,
|
||||
"onNavigationBarButtonTap": true,
|
||||
"onNavigationBarSearchInputChanged": true,
|
||||
"onNavigationBarSearchInputClicked": true,
|
||||
"onNavigationBarSearchInputConfirmed": true,
|
||||
"onNavigationBarSearchInputFocusChanged": true,
|
||||
"onPageNotFound": true,
|
||||
"onPageScroll": true,
|
||||
"onPullDownRefresh": true,
|
||||
"onReachBottom": true,
|
||||
"onReady": true,
|
||||
"onRenderTracked": true,
|
||||
"onRenderTriggered": true,
|
||||
"onResize": true,
|
||||
"onScopeDispose": true,
|
||||
"onServerPrefetch": true,
|
||||
"onShareAppMessage": true,
|
||||
"onShareTimeline": true,
|
||||
"onShow": true,
|
||||
"onTabItemTap": true,
|
||||
"onThemeChange": true,
|
||||
"onUnhandledRejection": true,
|
||||
"onUnload": true,
|
||||
"onUnmounted": true,
|
||||
"onUpdated": true,
|
||||
"onWatcherCleanup": true,
|
||||
"provide": true,
|
||||
"reactive": true,
|
||||
"readonly": true,
|
||||
"ref": true,
|
||||
"resolveComponent": true,
|
||||
"shallowReactive": true,
|
||||
"shallowReadonly": true,
|
||||
"shallowRef": true,
|
||||
"toRaw": true,
|
||||
"toRef": true,
|
||||
"toRefs": true,
|
||||
"toValue": true,
|
||||
"triggerRef": true,
|
||||
"unref": true,
|
||||
"useAttrs": true,
|
||||
"useCssModule": true,
|
||||
"useCssVars": true,
|
||||
"useId": true,
|
||||
"useModel": true,
|
||||
"useRequest": true,
|
||||
"useSlots": true,
|
||||
"useTemplateRef": true,
|
||||
"useUpload": true,
|
||||
"watch": true,
|
||||
"watchEffect": true,
|
||||
"watchPostEffect": true,
|
||||
"watchSyncEffect": true
|
||||
}
|
||||
}
|
||||
@ -1,97 +0,0 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
es2021: true,
|
||||
node: true
|
||||
},
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:vue/vue3-essential',
|
||||
// eslint-plugin-import 插件, @see https://www.npmjs.com/package/eslint-plugin-import
|
||||
'plugin:import/recommended',
|
||||
// eslint-config-airbnb-base 插件 已经改用 eslint-config-standard 插件
|
||||
'standard',
|
||||
// 1. 接入 prettier 的规则
|
||||
'prettier',
|
||||
'plugin:prettier/recommended',
|
||||
'./.eslintrc-auto-import.json'
|
||||
],
|
||||
overrides: [
|
||||
{
|
||||
env: {
|
||||
node: true
|
||||
},
|
||||
files: ['.eslintrc.{js,cjs}'],
|
||||
parserOptions: {
|
||||
sourceType: 'script'
|
||||
}
|
||||
}
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
parser: '@typescript-eslint/parser',
|
||||
sourceType: 'module'
|
||||
},
|
||||
plugins: [
|
||||
'@typescript-eslint',
|
||||
'vue',
|
||||
// 2. 加入 prettier 的 eslint 插件
|
||||
'prettier',
|
||||
// eslint-import-resolver-typescript 插件,@see https://www.npmjs.com/package/eslint-import-resolver-typescript
|
||||
'import'
|
||||
],
|
||||
rules: {
|
||||
// 3. 注意要加上这一句,开启 prettier 自动修复的功能
|
||||
'prettier/prettier': 'error',
|
||||
// turn on errors for missing imports
|
||||
'import/no-unresolved': 'off',
|
||||
// 对后缀的检测,否则 import 一个ts文件也会报错,需要手动添加'.ts', 增加了下面的配置后就不用了
|
||||
'import/extensions': [
|
||||
'error',
|
||||
'ignorePackages',
|
||||
{ js: 'never', jsx: 'never', ts: 'never', tsx: 'never' }
|
||||
],
|
||||
// 只允许1个默认导出,关闭,否则不能随意export xxx
|
||||
'import/prefer-default-export': ['off'],
|
||||
'no-console': ['off'],
|
||||
// 'no-unused-vars': ['off'],
|
||||
// '@typescript-eslint/no-unused-vars': ['off'],
|
||||
// 解决vite.config.ts报错问题
|
||||
'import/no-extraneous-dependencies': 'off',
|
||||
'no-plusplus': 'off',
|
||||
'no-shadow': 'off',
|
||||
'vue/multi-word-component-names': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'no-underscore-dangle': 'off',
|
||||
'no-use-before-define': 'off',
|
||||
'no-undef': 'off',
|
||||
'no-unused-vars': 'off',
|
||||
'no-param-reassign': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
// 避免 `eslint` 对于 `typescript` 函数重载的误报
|
||||
'no-redeclare': 'off',
|
||||
'@typescript-eslint/no-redeclare': 'error'
|
||||
},
|
||||
// eslint-import-resolver-typescript 插件,@see https://www.npmjs.com/package/eslint-import-resolver-typescript
|
||||
settings: {
|
||||
'import/parsers': {
|
||||
'@typescript-eslint/parser': ['.ts', '.tsx']
|
||||
},
|
||||
'import/resolver': {
|
||||
typescript: {}
|
||||
}
|
||||
},
|
||||
globals: {
|
||||
$t: true,
|
||||
uni: true,
|
||||
UniApp: true,
|
||||
wx: true,
|
||||
WechatMiniprogram: true,
|
||||
getCurrentPages: true,
|
||||
UniHelper: true,
|
||||
Page: true,
|
||||
App: true,
|
||||
NodeJS: true
|
||||
}
|
||||
}
|
||||
42
.gitignore
vendored
42
.gitignore
vendored
@ -1,42 +0,0 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
.hbuilderx
|
||||
|
||||
.stylelintcache
|
||||
.eslintcache
|
||||
|
||||
docs/.vitepress/dist
|
||||
docs/.vitepress/cache
|
||||
|
||||
# lock 文件还是不要了,我主要的版本写死就好了
|
||||
# pnpm-lock.yaml
|
||||
# package-lock.json
|
||||
|
||||
# TIPS:如果某些文件已经加入了版本管理,现在重新加入 .gitignore 是不生效的,需要执行下面的操作
|
||||
# `git rm -r --cached .` 然后提交 commit 即可。
|
||||
|
||||
# git rm -r --cached file1 file2 ## 针对某些文件
|
||||
# git rm -r --cached dir1 dir2 ## 针对某些文件夹
|
||||
# git rm -r --cached . ## 针对所有文件
|
||||
|
||||
# 更新 uni-app 官方版本
|
||||
# npx @dcloudio/uvm@latest
|
||||
@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
# Run the commit-msg hook
|
||||
npx --no-install commitlint --edit
|
||||
@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
# Run the pre-commit hook
|
||||
npx --no-install -- lint-staged
|
||||
6
.npmrc
6
.npmrc
@ -1,6 +0,0 @@
|
||||
# registry = https://registry.npmjs.org
|
||||
registry = https://registry.npmmirror.com
|
||||
|
||||
strict-peer-dependencies=false
|
||||
auto-install-peers=true
|
||||
shamefully-hoist=true
|
||||
@ -1,9 +0,0 @@
|
||||
# unplugin-auto-import 生成的类型文件,每次提交都改变,所以加入这里吧,与 .gitignore 配合使用
|
||||
auto-import.d.ts
|
||||
|
||||
# vite-plugin-uni-pages 生成的类型文件,每次切换分支都一堆不同的,所以直接 .gitignore
|
||||
uni-pages.d.ts
|
||||
|
||||
# 插件生成的文件
|
||||
src/pages.json
|
||||
src/manifest.json
|
||||
@ -1,30 +0,0 @@
|
||||
module.exports = {
|
||||
singleQuote: true,
|
||||
printWidth: 100,
|
||||
tabWidth: 2,
|
||||
useTabs: false,
|
||||
semi: false,
|
||||
trailingComma: 'none',
|
||||
endOfLine: 'auto',
|
||||
quoteProps: 'as-needed',
|
||||
jsxSingleQuote: false,
|
||||
bracketSpacing: true,
|
||||
jsxBracketSameLine: false,
|
||||
bracketSameLine: false,
|
||||
arrowParens: 'avoid',
|
||||
embeddedLanguageFormatting: 'auto',
|
||||
vueIndentScriptAndStyle: true,
|
||||
singleAttributePerLine: false,
|
||||
requirePragma: false,
|
||||
insertPragma: false,
|
||||
proseWrap: 'preserve',
|
||||
htmlWhitespaceSensitivity: 'ignore',
|
||||
overrides: [
|
||||
{
|
||||
files: '*.json',
|
||||
options: {
|
||||
trailingComma: 'none'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
src/uni_modules/
|
||||
@ -1,58 +0,0 @@
|
||||
// .stylelintrc.cjs
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: [
|
||||
// stylelint-config-standard 替换成了更宽松的 stylelint-config-recommended
|
||||
'stylelint-config-recommended',
|
||||
// stylelint-config-standard-scss 替换成了更宽松的 stylelint-config-recommended-scss
|
||||
'stylelint-config-recommended-scss',
|
||||
'stylelint-config-recommended-vue/scss',
|
||||
'stylelint-config-html/vue',
|
||||
'stylelint-config-recess-order'
|
||||
],
|
||||
plugins: ['stylelint-prettier'],
|
||||
overrides: [
|
||||
// 扫描 .vue/html 文件中的<style>标签内的样式
|
||||
{
|
||||
files: ['**/*.{vue,html}'],
|
||||
customSyntax: 'postcss-html'
|
||||
},
|
||||
{
|
||||
files: ['**/*.{css,scss}'],
|
||||
customSyntax: 'postcss-scss'
|
||||
}
|
||||
],
|
||||
// 自定义规则
|
||||
rules: {
|
||||
'prettier/prettier': true,
|
||||
// 允许 global 、export 、v-deep等伪类
|
||||
'selector-pseudo-class-no-unknown': [
|
||||
true,
|
||||
{
|
||||
ignorePseudoClasses: ['global', 'export', 'v-deep', 'deep']
|
||||
}
|
||||
],
|
||||
'unit-no-unknown': [
|
||||
true,
|
||||
{
|
||||
ignoreUnits: ['rpx']
|
||||
}
|
||||
],
|
||||
// 处理小程序page标签不认识的问题
|
||||
'selector-type-no-unknown': [
|
||||
true,
|
||||
{
|
||||
ignoreTypes: ['page']
|
||||
}
|
||||
],
|
||||
'comment-empty-line-before': 'never', // never|always|always-multi-line|never-multi-line
|
||||
'custom-property-empty-line-before': 'never',
|
||||
'no-empty-source': null,
|
||||
'comment-no-empty': null,
|
||||
'no-duplicate-selectors': null,
|
||||
'scss/comment-no-empty': null,
|
||||
'selector-class-pattern': null,
|
||||
'font-family-no-missing-generic-family-keyword': null
|
||||
}
|
||||
}
|
||||
18
.vscode/extensions.json
vendored
18
.vscode/extensions.json
vendored
@ -1,18 +0,0 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"vue.volar",
|
||||
"stylelint.vscode-stylelint",
|
||||
"esbenp.prettier-vscode",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"antfu.unocss",
|
||||
"antfu.iconify",
|
||||
"evils.uniapp-vscode",
|
||||
"uni-helper.uni-helper-vscode",
|
||||
"uni-helper.uni-app-schemas-vscode",
|
||||
"uni-helper.uni-highlight-vscode",
|
||||
"uni-helper.uni-ui-snippets-vscode",
|
||||
"uni-helper.uni-app-snippets-vscode",
|
||||
"mrmlnc.vscode-json5",
|
||||
"streetsidesoftware.code-spell-checker"
|
||||
]
|
||||
}
|
||||
63
.vscode/settings.json
vendored
63
.vscode/settings.json
vendored
@ -1,63 +0,0 @@
|
||||
{
|
||||
// 默认格式化工具选择prettier
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
// 保存的时候自动格式化
|
||||
"editor.formatOnSave": true,
|
||||
//开启自动修复
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": "explicit",
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.fixAll.stylelint": "explicit"
|
||||
},
|
||||
// 配置stylelint检查的文件类型范围
|
||||
"stylelint.validate": ["css", "scss", "vue", "html"], // 与package.json的scripts对应
|
||||
"stylelint.enable": true,
|
||||
"css.validate": false,
|
||||
"less.validate": false,
|
||||
"scss.validate": false,
|
||||
"[shellscript]": {
|
||||
"editor.defaultFormatter": "foxundermoon.shell-format"
|
||||
},
|
||||
"[dotenv]": {
|
||||
"editor.defaultFormatter": "foxundermoon.shell-format"
|
||||
},
|
||||
"[vue]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[jsonc]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
// 配置语言的文件关联
|
||||
"files.associations": {
|
||||
"pages.json": "jsonc", // pages.json 可以写注释
|
||||
"manifest.json": "jsonc" // manifest.json 可以写注释
|
||||
},
|
||||
"cSpell.words": [
|
||||
"climblee",
|
||||
"commitlint",
|
||||
"dcloudio",
|
||||
"iconfont",
|
||||
"qrcode",
|
||||
"refresherrefresh",
|
||||
"scrolltolower",
|
||||
"tabbar",
|
||||
"unibest",
|
||||
"uvui",
|
||||
"WechatMiniprogram"
|
||||
],
|
||||
"typescript.tsdk": "node_modules\\typescript\\lib",
|
||||
// 控制相关文件嵌套展示
|
||||
"explorer.fileNesting.enabled": true,
|
||||
"explorer.fileNesting.expand": false,
|
||||
"explorer.fileNesting.patterns": {
|
||||
"*.ts": "$(capture).test.ts, $(capture).test.tsx",
|
||||
"*.tsx": "$(capture).test.ts, $(capture).test.tsx",
|
||||
// "*.env": "$(capture).env.*",
|
||||
"CHANGELOG.md": "CHANGELOG*",
|
||||
"package.json": "pnpm-lock.yaml,pnpm-workspace.yaml,LICENSE,.gitattributes,.gitignore,.gitpod.yml,CNAME,.npmrc,.browserslistrc",
|
||||
".eslintrc.cjs": ".eslintignore,.prettierignore,.stylelintignore,.commitlintrc.*,.prettierrc.*,.stylelintrc.*,.eslintrc-auto-import.json,.editorconfig,.commitlint.cjs"
|
||||
}
|
||||
}
|
||||
56
.vscode/vue3.code-snippets
vendored
56
.vscode/vue3.code-snippets
vendored
@ -1,56 +0,0 @@
|
||||
{
|
||||
// Place your unibest 工作区 snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
|
||||
// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
|
||||
// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
|
||||
// used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
|
||||
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
|
||||
// Placeholders with the same ids are connected.
|
||||
// Example:
|
||||
// "Print to console": {
|
||||
// "scope": "javascript,typescript",
|
||||
// "prefix": "log",
|
||||
// "body": [
|
||||
// "console.log('$1');",
|
||||
// "$2"
|
||||
// ],
|
||||
// "description": "Log output to console"
|
||||
// }
|
||||
"Print unibest Vue3 SFC": {
|
||||
"scope": "vue",
|
||||
"prefix": "v3",
|
||||
"body": [
|
||||
"<route lang=\"json5\" type=\"page\">",
|
||||
"{",
|
||||
" layout: 'default',",
|
||||
" style: {",
|
||||
" navigationBarTitleText: '$1',",
|
||||
" },",
|
||||
"}",
|
||||
"</route>\n",
|
||||
"<template>",
|
||||
" <view class=\"\">$2</view>",
|
||||
"</template>\n",
|
||||
"<script lang=\"ts\" setup>",
|
||||
"//$3",
|
||||
"</script>\n",
|
||||
"<style lang=\"scss\" scoped>",
|
||||
"//$4",
|
||||
"</style>\n",
|
||||
],
|
||||
},
|
||||
"Print unibest style": {
|
||||
"scope": "vue",
|
||||
"prefix": "st",
|
||||
"body": ["<style lang=\"scss\" scoped>", "//", "</style>\n"],
|
||||
},
|
||||
"Print unibest script": {
|
||||
"scope": "vue",
|
||||
"prefix": "sc",
|
||||
"body": ["<script lang=\"ts\" setup>", "//$3", "</script>\n"],
|
||||
},
|
||||
"Print unibest template": {
|
||||
"scope": "vue",
|
||||
"prefix": "te",
|
||||
"body": ["<template>", " <view class=\"\">$1</view>", "</template>\n"],
|
||||
},
|
||||
}
|
||||
21
LICENSE
21
LICENSE
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 菲鸽
|
||||
|
||||
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.
|
||||
98
README.md
98
README.md
@ -1,23 +1,93 @@
|
||||
`unibest` 是一个 uniapp 跨端解决方案,由 `uniapp` + `Vue3` + `Ts` + `Vite4` + `UnoCss` + `VSCode`(可选 `webstorm`) 实现。它使用了最新的前端技术栈,可以通过命令行方式运行 `web`、`小程序` 和 `App`,同时也支持 `HBuilderX` 运行,当前版本为 `HBuilderX` 运行版本。如需通过命令行运行,请安装命令行版(<a href="https://github.com/codercup/unibest" target="_blank">unibest</a>)。
|
||||
# uniapp-星勤
|
||||
|
||||
`unibest` 内置了 `约定式路由`、`layout布局`、`请求封装`、`请求拦截`、`登录拦截`、`UnoCSS`、`i18n多语言` 等基础功能,提供了 `代码提示`、`自动格式化`、`统一配置`、`代码片段` 等辅助功能,让你编写 `uniapp` 拥有 `best` 体验 ( `unibest 的由来`)。
|
||||
|
||||
## ⚙️ 环境
|
||||
|
||||
- node>=18
|
||||
- pnpm>=7.30
|
||||
## Getting started
|
||||
|
||||
## 📂 安装
|
||||
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
|
||||
|
||||
```bash
|
||||
# HBuilderX 模板,方便使用 uniCloud 云开发 (未来可以对接 uni-app x)
|
||||
pnpm create unibest my-project -t hbx-base # hbx的base模板
|
||||
pnpm create unibest my-project -t hbx-demo # hbx的demo模板,包含所有的demo
|
||||
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
|
||||
|
||||
# 执行 `pnpm i` 安装依赖
|
||||
pnpm i
|
||||
## Add your files
|
||||
|
||||
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
|
||||
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
|
||||
|
||||
```
|
||||
cd existing_repo
|
||||
git remote add origin http://code.star-lock.cn/StarlockTeam/starwork-uniapp.git
|
||||
git branch -M master
|
||||
git push -uf origin master
|
||||
```
|
||||
|
||||
## 📦 使用 `HBuilderX` 打开
|
||||
## Integrate with your tools
|
||||
|
||||
在 `HBuilderX` 运行(支持热更新)或 编译
|
||||
- [ ] [Set up project integrations](http://code.star-lock.cn/StarlockTeam/starwork-uniapp/-/settings/integrations)
|
||||
|
||||
## Collaborate with your team
|
||||
|
||||
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
|
||||
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
|
||||
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
|
||||
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
|
||||
- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
|
||||
|
||||
## Test and Deploy
|
||||
|
||||
Use the built-in continuous integration in GitLab.
|
||||
|
||||
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
|
||||
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
|
||||
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
|
||||
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
|
||||
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
|
||||
|
||||
***
|
||||
|
||||
# Editing this README
|
||||
|
||||
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
|
||||
|
||||
## Suggestions for a good README
|
||||
|
||||
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
|
||||
|
||||
## Name
|
||||
Choose a self-explaining name for your project.
|
||||
|
||||
## Description
|
||||
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
|
||||
|
||||
## Badges
|
||||
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
|
||||
|
||||
## Visuals
|
||||
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
|
||||
|
||||
## Installation
|
||||
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
|
||||
|
||||
## Usage
|
||||
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
|
||||
|
||||
## Support
|
||||
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
|
||||
|
||||
## Roadmap
|
||||
If you have ideas for releases in the future, it is a good idea to list them in the README.
|
||||
|
||||
## Contributing
|
||||
State if you are open to contributions and what your requirements are for accepting them.
|
||||
|
||||
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
|
||||
|
||||
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
|
||||
|
||||
## Authors and acknowledgment
|
||||
Show your appreciation to those who have contributed to the project.
|
||||
|
||||
## License
|
||||
For open source projects, say how it is licensed.
|
||||
|
||||
## Project status
|
||||
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
|
||||
|
||||
20
env/.env
vendored
20
env/.env
vendored
@ -1,20 +0,0 @@
|
||||
VITE_APP_TITLE='星星勤务'
|
||||
VITE_APP_PORT=9000
|
||||
|
||||
VITE_UNI_APPID='__UNI__58536F2'
|
||||
VITE_WX_APPID='wxa2abb91f64032a2b'
|
||||
|
||||
# h5部署网站的base,配置到 manifest.config.ts 里的 h5.router.base
|
||||
VITE_APP_PUBLIC_BASE=/
|
||||
|
||||
# h5是否需要配置代理
|
||||
VITE_APP_PROXY=false
|
||||
VITE_APP_PROXY_PREFIX='/api'
|
||||
|
||||
VITE_SERVER_BASEURL='https://dev.work.star-lock.cn/api'
|
||||
|
||||
VITE_APP_ENV='XHJ_DEV'
|
||||
|
||||
VITE_APP_VERSION='1.0.0'
|
||||
VITE_APP_BUILD_NUMBER=1
|
||||
|
||||
12
env/.env.sky_dev
vendored
12
env/.env.sky_dev
vendored
@ -1,12 +0,0 @@
|
||||
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
|
||||
NODE_ENV='development'
|
||||
# 是否去除console 和 debugger
|
||||
VITE_DELETE_CONSOLE=false
|
||||
# 是否开启sourcemap
|
||||
VITE_SHOW_SOURCEMAP=true
|
||||
|
||||
VITE_SERVER_BASEURL='https://dev.work.star-lock.cn'
|
||||
|
||||
VITE_APP_TITLE='斯凯签勤_DEV'
|
||||
|
||||
VITE_APP_ENV='SKY_DEV'
|
||||
10
env/.env.sky_pre
vendored
10
env/.env.sky_pre
vendored
@ -1,10 +0,0 @@
|
||||
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
|
||||
NODE_ENV='development'
|
||||
# 是否去除console 和 debugger
|
||||
VITE_DELETE_CONSOLE=false
|
||||
|
||||
VITE_SERVER_BASEURL='https://pre.work.star-lock.cn'
|
||||
|
||||
VITE_APP_TITLE='斯凯签勤_PRE'
|
||||
|
||||
VITE_APP_ENV='SKY_PRE'
|
||||
12
env/.env.sky_release
vendored
12
env/.env.sky_release
vendored
@ -1,12 +0,0 @@
|
||||
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
|
||||
NODE_ENV='development'
|
||||
# 是否去除console 和 debugger
|
||||
VITE_DELETE_CONSOLE=true
|
||||
# 是否开启sourcemap
|
||||
VITE_SHOW_SOURCEMAP=false
|
||||
|
||||
VITE_SERVER_BASEURL='https://pre.work.star-lock.cn'
|
||||
|
||||
VITE_APP_TITLE='斯凯签勤'
|
||||
|
||||
VITE_APP_ENV='SKY'
|
||||
12
env/.env.xhj_dev
vendored
12
env/.env.xhj_dev
vendored
@ -1,12 +0,0 @@
|
||||
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
|
||||
NODE_ENV='development'
|
||||
# 是否去除console 和 debugger
|
||||
VITE_DELETE_CONSOLE=false
|
||||
# 是否开启sourcemap
|
||||
VITE_SHOW_SOURCEMAP=true
|
||||
|
||||
VITE_SERVER_BASEURL='https://dev.work.star-lock.cn'
|
||||
|
||||
VITE_APP_TITLE='星星勤务_DEV'
|
||||
|
||||
VITE_APP_ENV='XHJ_DEV'
|
||||
10
env/.env.xhj_pre
vendored
10
env/.env.xhj_pre
vendored
@ -1,10 +0,0 @@
|
||||
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
|
||||
NODE_ENV='development'
|
||||
# 是否去除console 和 debugger
|
||||
VITE_DELETE_CONSOLE=false
|
||||
|
||||
VITE_SERVER_BASEURL='https://pre.work.star-lock.cn'
|
||||
|
||||
VITE_APP_TITLE='星星勤务_PRE'
|
||||
|
||||
VITE_APP_ENV='XHJ_PRE'
|
||||
13
env/.env.xhj_release
vendored
13
env/.env.xhj_release
vendored
@ -1,13 +0,0 @@
|
||||
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
|
||||
NODE_ENV='development'
|
||||
# 是否去除console 和 debugger
|
||||
VITE_DELETE_CONSOLE=true
|
||||
# 是否开启sourcemap
|
||||
VITE_SHOW_SOURCEMAP=false
|
||||
|
||||
|
||||
VITE_SERVER_BASEURL='https://work.star-lock.cn'
|
||||
|
||||
VITE_APP_TITLE='星星勤务'
|
||||
|
||||
VITE_APP_ENV='XHJ'
|
||||
BIN
favicon.ico
BIN
favicon.ico
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB |
26
index.html
26
index.html
@ -1,26 +0,0 @@
|
||||
<!doctype html>
|
||||
<html build-time="%BUILD_TIME%">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
|
||||
<script>
|
||||
var coverSupport =
|
||||
'CSS' in window &&
|
||||
typeof CSS.supports === 'function' &&
|
||||
(CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
|
||||
document.write(
|
||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||
(coverSupport ? ', viewport-fit=cover' : '') +
|
||||
'" />',
|
||||
)
|
||||
</script>
|
||||
<title>unibest</title>
|
||||
<!--preload-links-->
|
||||
<!--app-context-->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"><!--app-html--></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,135 +0,0 @@
|
||||
// manifest.config.ts
|
||||
import { defineManifestConfig } from '@uni-helper/vite-plugin-uni-manifest'
|
||||
// import path from 'node:path'
|
||||
import * as path from 'path'
|
||||
import { loadEnv } from 'vite'
|
||||
|
||||
// 获取环境变量的范例
|
||||
const env = loadEnv(process.env.NODE_ENV!, path.resolve(process.cwd(), 'env'))
|
||||
const {
|
||||
VITE_APP_TITLE,
|
||||
VITE_UNI_APPID,
|
||||
VITE_WX_APPID,
|
||||
VITE_APP_PUBLIC_BASE,
|
||||
VITE_FALLBACK_LOCALE
|
||||
} = env
|
||||
|
||||
export default defineManifestConfig({
|
||||
name: VITE_APP_TITLE,
|
||||
appid: VITE_UNI_APPID,
|
||||
description: '',
|
||||
versionName: '1.0.0',
|
||||
versionCode: '100',
|
||||
transformPx: false,
|
||||
locale: VITE_FALLBACK_LOCALE, // 'zh-Hans'
|
||||
h5: {
|
||||
router: {
|
||||
base: VITE_APP_PUBLIC_BASE
|
||||
}
|
||||
},
|
||||
/* 5+App特有相关 */
|
||||
'app-plus': {
|
||||
usingComponents: true,
|
||||
nvueStyleCompiler: 'uni-app',
|
||||
compilerVersion: 3,
|
||||
compatible: {
|
||||
ignoreVersion: true
|
||||
},
|
||||
splashscreen: {
|
||||
alwaysShowBeforeRender: true,
|
||||
waiting: true,
|
||||
autoclose: true,
|
||||
delay: 0
|
||||
},
|
||||
/* 模块配置 */
|
||||
modules: {},
|
||||
/* 应用发布信息 */
|
||||
distribute: {
|
||||
/* android打包配置 */
|
||||
android: {
|
||||
minSdkVersion: 29,
|
||||
targetSdkVersion: 30,
|
||||
abiFilters: ['armeabi-v7a', 'arm64-v8a'],
|
||||
permissions: [
|
||||
'<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>',
|
||||
'<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>',
|
||||
'<uses-permission android:name="android.permission.VIBRATE"/>',
|
||||
'<uses-permission android:name="android.permission.READ_LOGS"/>',
|
||||
'<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>',
|
||||
'<uses-feature android:name="android.hardware.camera.autofocus"/>',
|
||||
'<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>',
|
||||
'<uses-permission android:name="android.permission.CAMERA"/>',
|
||||
'<uses-permission android:name="android.permission.GET_ACCOUNTS"/>',
|
||||
'<uses-permission android:name="android.permission.READ_PHONE_STATE"/>',
|
||||
'<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>',
|
||||
'<uses-permission android:name="android.permission.WAKE_LOCK"/>',
|
||||
'<uses-permission android:name="android.permission.FLASHLIGHT"/>',
|
||||
'<uses-feature android:name="android.hardware.camera"/>',
|
||||
'<uses-permission android:name="android.permission.WRITE_SETTINGS"/>'
|
||||
]
|
||||
},
|
||||
/* ios打包配置 */
|
||||
ios: {},
|
||||
/* SDK配置 */
|
||||
sdkConfigs: {},
|
||||
/* 图标配置 */
|
||||
icons: {
|
||||
android: {
|
||||
hdpi: 'static/app/icons/72x72.png',
|
||||
xhdpi: 'static/app/icons/96x96.png',
|
||||
xxhdpi: 'static/app/icons/144x144.png',
|
||||
xxxhdpi: 'static/app/icons/192x192.png'
|
||||
},
|
||||
ios: {
|
||||
appstore: 'static/app/icons/1024x1024.png',
|
||||
ipad: {
|
||||
app: 'static/app/icons/76x76.png',
|
||||
'app@2x': 'static/app/icons/152x152.png',
|
||||
notification: 'static/app/icons/20x20.png',
|
||||
'notification@2x': 'static/app/icons/40x40.png',
|
||||
'proapp@2x': 'static/app/icons/167x167.png',
|
||||
settings: 'static/app/icons/29x29.png',
|
||||
'settings@2x': 'static/app/icons/58x58.png',
|
||||
spotlight: 'static/app/icons/40x40.png',
|
||||
'spotlight@2x': 'static/app/icons/80x80.png'
|
||||
},
|
||||
iphone: {
|
||||
'app@2x': 'static/app/icons/120x120.png',
|
||||
'app@3x': 'static/app/icons/180x180.png',
|
||||
'notification@2x': 'static/app/icons/40x40.png',
|
||||
'notification@3x': 'static/app/icons/60x60.png',
|
||||
'settings@2x': 'static/app/icons/58x58.png',
|
||||
'settings@3x': 'static/app/icons/87x87.png',
|
||||
'spotlight@2x': 'static/app/icons/80x80.png',
|
||||
'spotlight@3x': 'static/app/icons/120x120.png'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
/* 快应用特有相关 */
|
||||
quickapp: {},
|
||||
/* 小程序特有相关 */
|
||||
'mp-weixin': {
|
||||
appid: VITE_WX_APPID,
|
||||
setting: {
|
||||
urlCheck: false
|
||||
},
|
||||
usingComponents: true
|
||||
// __usePrivacyCheck__: true,
|
||||
},
|
||||
'mp-alipay': {
|
||||
usingComponents: true,
|
||||
styleIsolation: 'shared'
|
||||
},
|
||||
'mp-baidu': {
|
||||
usingComponents: true
|
||||
},
|
||||
'mp-toutiao': {
|
||||
usingComponents: true
|
||||
},
|
||||
uniStatistics: {
|
||||
enable: false
|
||||
},
|
||||
vueVersion: '3'
|
||||
})
|
||||
160
package.json
160
package.json
@ -1,160 +0,0 @@
|
||||
{
|
||||
"name": "starwork-uniapp",
|
||||
"type": "commonjs",
|
||||
"version": "1.0.0",
|
||||
"engines": {
|
||||
"node": ">=18",
|
||||
"pnpm": ">=7.30"
|
||||
},
|
||||
"scripts": {
|
||||
"build:app-android-xhj_dev": "uni build -p app-android --mode xhj_dev",
|
||||
"build:app-android-sky_dev": "uni build -p app-android --mode sky_dev",
|
||||
"build:app-android-xhj_pre": "uni build -p app-android --mode xhj_pre",
|
||||
"build:app-android-sky_pre": "uni build -p app-android --mode sky_pre",
|
||||
"build:app-android-xhj_release": "uni build -p app-android --mode xhj_release",
|
||||
"build:app-android-sky_release": "uni build -p app-android --mode sky_release",
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"uvm": "npx @dcloudio/uvm@latest",
|
||||
"uvm-rm": "node ./scripts/postupgrade.js",
|
||||
"postuvm": "echo upgrade uni-app success!",
|
||||
"dev:app": "uni -p app",
|
||||
"dev:app-android": "uni -p app-android",
|
||||
"dev:app-ios": "uni -p app-ios",
|
||||
"dev:custom": "uni -p",
|
||||
"dev": "uni",
|
||||
"dev:h5": "uni",
|
||||
"dev:h5:ssr": "uni --ssr",
|
||||
"dev:mp": "uni -p mp-weixin",
|
||||
"dev:mp-alipay": "uni -p mp-alipay",
|
||||
"dev:mp-baidu": "uni -p mp-baidu",
|
||||
"dev:mp-jd": "uni -p mp-jd",
|
||||
"dev:mp-kuaishou": "uni -p mp-kuaishou",
|
||||
"dev:mp-lark": "uni -p mp-lark",
|
||||
"dev:mp-qq": "uni -p mp-qq",
|
||||
"dev:mp-toutiao": "uni -p mp-toutiao",
|
||||
"dev:mp-weixin": "uni -p mp-weixin",
|
||||
"dev:mp-xhs": "uni -p mp-xhs",
|
||||
"dev:quickapp-webview": "uni -p quickapp-webview",
|
||||
"dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
|
||||
"dev:quickapp-webview-union": "uni -p quickapp-webview-union",
|
||||
"build:app": "uni build -p app",
|
||||
"build:app-android": "uni build -p app-android",
|
||||
"build:app-ios": "uni build -p app-ios",
|
||||
"build:custom": "uni build -p",
|
||||
"build:h5": "uni build",
|
||||
"build": "uni build",
|
||||
"build:h5:ssr": "uni build --ssr",
|
||||
"build:mp-alipay": "uni build -p mp-alipay",
|
||||
"build:mp": "uni build -p mp-weixin",
|
||||
"build:mp-baidu": "uni build -p mp-baidu",
|
||||
"build:mp-jd": "uni build -p mp-jd",
|
||||
"build:mp-kuaishou": "uni build -p mp-kuaishou",
|
||||
"build:mp-lark": "uni build -p mp-lark",
|
||||
"build:mp-qq": "uni build -p mp-qq",
|
||||
"build:mp-toutiao": "uni build -p mp-toutiao",
|
||||
"build:mp-weixin": "uni build -p mp-weixin",
|
||||
"build:mp-xhs": "uni build -p mp-xhs",
|
||||
"build:quickapp-webview": "uni build -p quickapp-webview",
|
||||
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
|
||||
"build:quickapp-webview-union": "uni build -p quickapp-webview-union",
|
||||
"prepare": "git init && husky install ",
|
||||
"type-check": "vue-tsc --noEmit",
|
||||
"cz": "czg"
|
||||
},
|
||||
"lint-staged": {
|
||||
"**/*.{html,vue,ts,cjs,json,md}": [
|
||||
"prettier --write"
|
||||
],
|
||||
"**/*.{vue,js,ts,jsx,tsx}": [
|
||||
"eslint --cache --fix"
|
||||
],
|
||||
"**/*.{vue,css,scss,html}": [
|
||||
"stylelint --fix"
|
||||
]
|
||||
},
|
||||
"resolutions": {
|
||||
"bin-wrapper": "npm:bin-wrapper-china"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dcloudio/uni-app": "3.0.0-4020920240930001",
|
||||
"@dcloudio/uni-app-harmony": "3.0.0-4020920240930001",
|
||||
"@dcloudio/uni-app-plus": "3.0.0-4020920240930001",
|
||||
"@dcloudio/uni-components": "3.0.0-4020920240930001",
|
||||
"@dcloudio/uni-h5": "3.0.0-4020920240930001",
|
||||
"@dcloudio/uni-mp-alipay": "3.0.0-4020920240930001",
|
||||
"@dcloudio/uni-mp-baidu": "3.0.0-4020920240930001",
|
||||
"@dcloudio/uni-mp-jd": "3.0.0-4020920240930001",
|
||||
"@dcloudio/uni-mp-kuaishou": "3.0.0-4020920240930001",
|
||||
"@dcloudio/uni-mp-lark": "3.0.0-4020920240930001",
|
||||
"@dcloudio/uni-mp-qq": "3.0.0-4020920240930001",
|
||||
"@dcloudio/uni-mp-toutiao": "3.0.0-4020920240930001",
|
||||
"@dcloudio/uni-mp-weixin": "3.0.0-4020920240930001",
|
||||
"@dcloudio/uni-mp-xhs": "3.0.0-4020920240930001",
|
||||
"@dcloudio/uni-quickapp-webview": "3.0.0-4020920240930001",
|
||||
"dayjs": "1.11.10",
|
||||
"pinia": "2.0.36",
|
||||
"pinia-plugin-persistedstate": "3.2.1",
|
||||
"qs": "6.5.3",
|
||||
"vue": "3.4.21",
|
||||
"wot-design-uni": "1.5.1",
|
||||
"z-paging": "^2.8.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^18.6.1",
|
||||
"@commitlint/config-conventional": "^18.6.3",
|
||||
"@dcloudio/types": "^3.4.14",
|
||||
"@dcloudio/uni-automator": "3.0.0-4020920240930001",
|
||||
"@dcloudio/uni-cli-shared": "3.0.0-4020920240930001",
|
||||
"@dcloudio/uni-stacktracey": "3.0.0-4020920240930001",
|
||||
"@dcloudio/vite-plugin-uni": "3.0.0-4020920240930001",
|
||||
"@esbuild/darwin-arm64": "0.20.2",
|
||||
"@esbuild/darwin-x64": "0.20.2",
|
||||
"@iconify-json/bytesize": "^1.2.2",
|
||||
"@iconify-json/carbon": "^1.2.4",
|
||||
"@rollup/rollup-darwin-x64": "^4.28.0",
|
||||
"@types/node": "^20.17.9",
|
||||
"@types/wechat-miniprogram": "^3.4.8",
|
||||
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||
"@typescript-eslint/parser": "^6.21.0",
|
||||
"@uni-helper/uni-types": "1.0.0-alpha.3",
|
||||
"@uni-helper/vite-plugin-uni-layouts": "^0.1.10",
|
||||
"@uni-helper/vite-plugin-uni-manifest": "^0.2.7",
|
||||
"@uni-helper/vite-plugin-uni-pages": "0.2.20",
|
||||
"@uni-helper/vite-plugin-uni-platform": "^0.0.4",
|
||||
"@unocss/preset-legacy-compat": "^0.59.4",
|
||||
"@vue/runtime-core": "^3.5.13",
|
||||
"@vue/tsconfig": "^0.1.3",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"commitlint": "^18.6.1",
|
||||
"czg": "^1.9.4",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-config-standard": "^17.1.0",
|
||||
"eslint-import-resolver-typescript": "^3.7.0",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
"eslint-plugin-vue": "^9.32.0",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^15.2.10",
|
||||
"postcss": "^8.4.49",
|
||||
"postcss-html": "^1.7.0",
|
||||
"postcss-scss": "^4.0.9",
|
||||
"rollup-plugin-visualizer": "^5.12.0",
|
||||
"sass": "^1.77.8",
|
||||
"stylelint": "^16.11.0",
|
||||
"stylelint-config-html": "^1.1.0",
|
||||
"stylelint-config-recess-order": "^4.6.0",
|
||||
"stylelint-config-recommended": "^14.0.1",
|
||||
"stylelint-config-recommended-scss": "^14.1.0",
|
||||
"stylelint-config-recommended-vue": "^1.5.0",
|
||||
"stylelint-prettier": "^5.0.2",
|
||||
"terser": "^5.36.0",
|
||||
"typescript": "^5.7.2",
|
||||
"unocss": "^0.58.9",
|
||||
"unocss-applet": "^0.7.8",
|
||||
"unplugin-auto-import": "^0.17.8",
|
||||
"vite": "5.2.8",
|
||||
"vite-plugin-restart": "^0.4.2",
|
||||
"vue-tsc": "^1.8.27"
|
||||
}
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
import { defineUniPages } from '@uni-helper/vite-plugin-uni-pages'
|
||||
|
||||
export default defineUniPages({
|
||||
globalStyle: {
|
||||
navigationStyle: 'default',
|
||||
navigationBarTitleText: '星星勤务',
|
||||
navigationBarBackgroundColor: '#f8f8f8',
|
||||
navigationBarTextStyle: 'black',
|
||||
backgroundColor: '#FFFFFF'
|
||||
},
|
||||
easycom: {
|
||||
autoscan: true,
|
||||
custom: {
|
||||
'^wd-(.*)': 'wot-design-uni/components/wd-$1/wd-$1.vue',
|
||||
'^(?!z-paging-refresh|z-paging-load-more)z-paging(.*)':
|
||||
'z-paging/components/z-paging$1/z-paging$1.vue'
|
||||
}
|
||||
},
|
||||
tabBar: {
|
||||
color: '#0d0f10',
|
||||
selectedColor: '#255cf7',
|
||||
backgroundColor: '#FFFFFF',
|
||||
borderStyle: 'black',
|
||||
height: '50px',
|
||||
fontSize: '10px',
|
||||
iconWidth: '24px',
|
||||
spacing: '5px',
|
||||
list: [
|
||||
{
|
||||
iconPath: 'static/tabbar/home.png',
|
||||
selectedIconPath: 'static/tabbar/home_selected.png',
|
||||
pagePath: 'pages/home/home',
|
||||
text: '首页'
|
||||
},
|
||||
{
|
||||
iconPath: 'static/tabbar/workbench.png',
|
||||
selectedIconPath: 'static/tabbar/workbench_selected.png',
|
||||
pagePath: 'pages/workbench/workbench',
|
||||
text: '工作台'
|
||||
},
|
||||
{
|
||||
iconPath: 'static/tabbar/notification.png',
|
||||
selectedIconPath: 'static/tabbar/notification_selected.png',
|
||||
pagePath: 'pages/notification/notification',
|
||||
text: '消息'
|
||||
},
|
||||
{
|
||||
iconPath: 'static/tabbar/mine.png',
|
||||
selectedIconPath: 'static/tabbar/mine_selected.png',
|
||||
pagePath: 'pages/mine/mine',
|
||||
text: '我的'
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
@ -1,7 +0,0 @@
|
||||
{
|
||||
"pages": [
|
||||
{
|
||||
"path": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
12359
pnpm-lock.yaml
generated
12359
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,36 +0,0 @@
|
||||
// # 执行 `pnpm upgrade` 后会升级 `uniapp` 相关依赖
|
||||
// # 在升级完后,会自动添加很多无用依赖,这需要删除以减小依赖包体积
|
||||
// # 只需要执行下面的命令即可
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { exec } = require('child_process')
|
||||
|
||||
// 定义要执行的命令
|
||||
const dependencies = [
|
||||
'@dcloudio/uni-app-harmony',
|
||||
// TODO: 如果需要某个平台的小程序,请手动删除或注释掉
|
||||
'@dcloudio/uni-mp-alipay',
|
||||
'@dcloudio/uni-mp-baidu',
|
||||
'@dcloudio/uni-mp-jd',
|
||||
'@dcloudio/uni-mp-kuaishou',
|
||||
'@dcloudio/uni-mp-lark',
|
||||
'@dcloudio/uni-mp-qq',
|
||||
'@dcloudio/uni-mp-toutiao',
|
||||
'@dcloudio/uni-mp-xhs',
|
||||
'@dcloudio/uni-quickapp-webview',
|
||||
// i18n模板要注释掉下面的
|
||||
'vue-i18n'
|
||||
]
|
||||
|
||||
// 使用exec执行命令
|
||||
exec(`pnpm un ${dependencies.join(' ')}`, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
// 如果有错误,打印错误信息
|
||||
console.error(`执行出错: ${error}`)
|
||||
return
|
||||
}
|
||||
// 打印正常输出
|
||||
console.log(`stdout: ${stdout}`)
|
||||
// 如果有错误输出,也打印出来
|
||||
console.error(`stderr: ${stderr}`)
|
||||
})
|
||||
48
src/App.vue
48
src/App.vue
@ -1,48 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
|
||||
|
||||
onLaunch(() => {
|
||||
console.log('App Launch')
|
||||
})
|
||||
onShow(() => {
|
||||
console.log('App Show')
|
||||
})
|
||||
onHide(() => {
|
||||
console.log('App Hide')
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/* stylelint-disable selector-type-no-unknown */
|
||||
|
||||
html,
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
button::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
swiper,
|
||||
scroll-view {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.uni-scroll-view-refresher {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
.wd-tabs__nav {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
.wd-tabs {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
</style>
|
||||
@ -1,81 +0,0 @@
|
||||
<template>
|
||||
<wd-popup
|
||||
v-model="visible"
|
||||
custom-style="border-top-left-radius: 0.3125rem;
|
||||
border-top-right-radius: 0.3125rem;background-color:#f6f8fc"
|
||||
position="bottom"
|
||||
@close="handleClose"
|
||||
>
|
||||
<view class="box-border">
|
||||
<view class="flex p-3 flex-justify-center">
|
||||
<view class="font-bold text-4">{{ title }}</view>
|
||||
<wd-icon
|
||||
class="position-absolute right-3 top-4.5 color-gray"
|
||||
name="close"
|
||||
size="15"
|
||||
@click="handleClose"
|
||||
/>
|
||||
</view>
|
||||
<view class="">
|
||||
<slot name="child"></slot>
|
||||
</view>
|
||||
<wd-button
|
||||
v-if="!noSure"
|
||||
@click="
|
||||
() => {
|
||||
onSure()
|
||||
handleClose()
|
||||
}
|
||||
"
|
||||
class="mx-3 my-5"
|
||||
block
|
||||
>
|
||||
确定
|
||||
</wd-button>
|
||||
<view v-else class="mx-3 my-5"></view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const props = defineProps({
|
||||
// 标题
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 关闭回调
|
||||
onclose: {
|
||||
type: Function,
|
||||
default: () => {},
|
||||
required: true
|
||||
},
|
||||
// 是否显示
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: true
|
||||
},
|
||||
// 确定回调
|
||||
onSure: {
|
||||
type: Function,
|
||||
default: () => {}
|
||||
},
|
||||
// 不要确定按钮
|
||||
noSure: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
const visible = ref(props.show)
|
||||
watchEffect(() => {
|
||||
visible.value = props.show
|
||||
})
|
||||
const handleClose = () => {
|
||||
visible.value = false
|
||||
props.onclose()
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
//
|
||||
</style>
|
||||
@ -1,68 +0,0 @@
|
||||
<template>
|
||||
<view class="mx-2">
|
||||
<view class="flex flex-row items-center py-3.5">
|
||||
<view class="mr-0.5" :class="isMust ? 'color-red' : 'color-transparent'">*</view>
|
||||
<view v-if="text">{{ text }}</view>
|
||||
<view v-if="$slots.leftChild">
|
||||
<slot name="leftChild"></slot>
|
||||
</view>
|
||||
<view v-if="$slots.child" class="flex-1 flex flex-row mx-2">
|
||||
<slot name="child" class="flex-1"></slot>
|
||||
</view>
|
||||
<view v-if="!$slots.child" class="flex-1 flex flex-row flex-justify-end items-center">
|
||||
<view v-if="!value" class="color-gray">{{ hint }}</view>
|
||||
<view v-else class="color-[#656567]">{{ value }}</view>
|
||||
<wd-icon
|
||||
v-if="isNext"
|
||||
name="arrow-right ml-1.5 mr-0.5"
|
||||
class="text-gray"
|
||||
size="22"
|
||||
></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="!noLine" class="hpx bg-gray-100 mx-2.5"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const props = defineProps({
|
||||
// 标题
|
||||
text: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 是否必填
|
||||
isMust: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 显示的值
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 是否显示下一步
|
||||
isNext: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 没有下划线
|
||||
noLine: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 无value时的提示
|
||||
hint: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
}
|
||||
// 没有child时使用选择模版
|
||||
})
|
||||
//
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
background-color: #f6f8fc;
|
||||
}
|
||||
</style>
|
||||
@ -1,73 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<wd-tabbar
|
||||
v-model="index"
|
||||
fixed
|
||||
safeAreaInsetBottom
|
||||
active-color="#255cf7"
|
||||
inactive-color="#0d0f10"
|
||||
placeholder
|
||||
@change="change"
|
||||
>
|
||||
<wd-tabbar-item
|
||||
v-for="(item, index) in list"
|
||||
:key="index"
|
||||
:is-dot="item.isDot || false"
|
||||
:title="item.title"
|
||||
:value="item.value || 0"
|
||||
:icon="item.icon"
|
||||
></wd-tabbar-item>
|
||||
</wd-tabbar>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const index = ref<number>(0)
|
||||
|
||||
defineOptions({
|
||||
options: {
|
||||
styleIsolation: 'shared'
|
||||
}
|
||||
})
|
||||
|
||||
const props = defineProps({
|
||||
defaultIndex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
list: {
|
||||
type: Array<TabBarItem>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const emits = defineEmits(['change'])
|
||||
|
||||
onMounted(() => {
|
||||
index.value = props.defaultIndex
|
||||
})
|
||||
|
||||
const change = (index: number) => {
|
||||
emits('change', index)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.wd-icon) {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
:deep(.wd-tabbar-item__body-title) {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
:deep(.wd-badge__content) {
|
||||
top: 5px !important;
|
||||
}
|
||||
|
||||
:deep(.wd-tabbar) {
|
||||
background: #f4f5fa;
|
||||
}
|
||||
</style>
|
||||
@ -1,95 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<wd-popup v-model="show" custom-style="border-radius:24rpx;" :close-on-click-modal="false">
|
||||
<view class="w-75">
|
||||
<view v-if="title" class="font-bold text-4 text-center pt-4">{{ title }}</view>
|
||||
<view class="text-3.5 w-60 pl-7.5 py-4 custom-color-black">
|
||||
<slot v-if="$slots.default"></slot>
|
||||
<view class="break-all" v-else>{{ content }}</view>
|
||||
</view>
|
||||
<view class="flex flex-items-center text-center border-[#ebebeb] border-t-1 border-t-solid">
|
||||
<view
|
||||
v-if="showCancel"
|
||||
class="w-1/2 py-3 text-4 font-bold border-r-1 border-r-solid border-[#ebebeb]"
|
||||
:style="{ color: cancelColor }"
|
||||
@click="cancel"
|
||||
>
|
||||
{{ cancelText }}
|
||||
</view>
|
||||
<view
|
||||
class="w-1/2 py-3 text-4 font-bold"
|
||||
:class="[showCancel ? 'w-1/2' : 'w-full']"
|
||||
:style="{ color: confirmColor }"
|
||||
@click="confirm"
|
||||
>
|
||||
{{ confirmText }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const show = ref(false)
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
cancelText: {
|
||||
type: String,
|
||||
default: '取消'
|
||||
},
|
||||
confirmText: {
|
||||
type: String,
|
||||
default: '确定'
|
||||
},
|
||||
showCancel: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
cancelColor: {
|
||||
type: String,
|
||||
default: '#0d0f10'
|
||||
},
|
||||
confirmColor: {
|
||||
type: String,
|
||||
default: '#255cf7'
|
||||
},
|
||||
controlModal: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const showModal = () => {
|
||||
show.value = true
|
||||
}
|
||||
|
||||
const hideModal = () => {
|
||||
show.value = false
|
||||
}
|
||||
|
||||
const emits = defineEmits(['cancel', 'confirm'])
|
||||
|
||||
const cancel = async () => {
|
||||
emits('cancel')
|
||||
show.value = props.controlModal
|
||||
}
|
||||
|
||||
const confirm = async () => {
|
||||
emits('confirm')
|
||||
show.value = props.controlModal
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
showModal,
|
||||
hideModal
|
||||
})
|
||||
</script>
|
||||
@ -1,88 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<wd-popup v-model="show" position="left" @close="closePopup">
|
||||
<view class="w-80 bg-[#f3f5fa] pos-relative h-full" v-if="systemInfo">
|
||||
<view
|
||||
:style="{ paddingTop: systemInfo.safeAreaInsets?.top + 'px' }"
|
||||
class="h-12 pt-1 flex flex-items-center flex-justify-between mx-4 custom-color-black"
|
||||
>
|
||||
<view class="text-4 font-bold">我的团队</view>
|
||||
<view class="rounded-50% bg-[#e2e5ea] flex-justify-center flex-items-center flex w-6 h-6">
|
||||
<wd-icon name="refresh" size="14px"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view scroll-y="true" :style="{ height: systemInfo.safeArea?.height - 128 + 'px' }">
|
||||
<view class="pb-10">
|
||||
<view
|
||||
class="flex flex-items-center bg-white shadow-sm p-2 mx-2 rounded-2 mt-2"
|
||||
v-for="(item, index) in [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 11, 12, 13, 14, 15]"
|
||||
:key="index"
|
||||
>
|
||||
<image
|
||||
src="/static/images/icon_team_join.png"
|
||||
mode="aspectFill"
|
||||
class="w-5 h-5 mx-2"
|
||||
></image>
|
||||
<view>
|
||||
<view class="text-3.5">06066322的互联</view>
|
||||
<image
|
||||
src="/static/images/icon_team.webp"
|
||||
mode="widthFix"
|
||||
class="w-10 mt-1"
|
||||
></image>
|
||||
</view>
|
||||
<image
|
||||
src="/static/images/icon_setting.webp"
|
||||
mode="aspectFill"
|
||||
class="w-4 h-4 ml-a"
|
||||
></image>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="pb-safe bottom-0 pos-absolute w-full color-[#515357] bg-[#f3f5fa]">
|
||||
<wd-divider color="#e6e7ec"></wd-divider>
|
||||
<view class="flex-items-center flex flex-justify-around px-5">
|
||||
<view>创建团队</view>
|
||||
<wd-divider color="#bdbfc4" vertical />
|
||||
<view>加入团队</view>
|
||||
</view>
|
||||
<wd-divider color="#e6e7ec"></wd-divider>
|
||||
<view class="text-center pb-4">快捷添加我的设备</view>
|
||||
</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useBasicStore } from '@/store'
|
||||
import GetSystemInfoResult = UniNamespace.GetSystemInfoResult
|
||||
|
||||
const $basic = useBasicStore()
|
||||
|
||||
const systemInfo = ref<GetSystemInfoResult>(null)
|
||||
const show = ref<boolean>(false)
|
||||
|
||||
onMounted(async () => {
|
||||
systemInfo.value = await $basic.getSystemInfo()
|
||||
})
|
||||
|
||||
const closePopup = () => {
|
||||
uni.showTabBar()
|
||||
}
|
||||
|
||||
const showModal = () => {
|
||||
uni.hideTabBar()
|
||||
show.value = true
|
||||
}
|
||||
|
||||
const hideModal = () => {
|
||||
uni.showTabBar()
|
||||
show.value = false
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
showModal,
|
||||
hideModal
|
||||
})
|
||||
</script>
|
||||
@ -1,94 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<view v-if="systemInfo" :style="{ marginTop: systemInfo.safeAreaInsets?.top + 'px' }">
|
||||
<view
|
||||
v-if="mini"
|
||||
class="h-12 pt-1 pos-relative flex flex-justify-between flex-items-center text-4 font-bold custom-color-black"
|
||||
>
|
||||
<view class="ml-4 line-clamp-1 max-w-60 break-all">
|
||||
{{ title }}
|
||||
</view>
|
||||
<view class="mr-3 border-1 border-solid border-[#ebebeb] w-25 h-7 rounded-4">
|
||||
<view class="flex flex-items-center flex-justify-around px-2 h-7">
|
||||
<image class="w-6 h-6" src="/static/images/icon_nav_more.png"></image>
|
||||
<view class="h-4 w-0.25 bg-[#ebebeb]"></view>
|
||||
<image class="w-6 h-6" src="/static/images/icon_nav_close.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
v-else
|
||||
class="h-12 pt-1 pos-relative flex flex-justify-center flex-items-center text-4 font-bold custom-color-black"
|
||||
>
|
||||
<image
|
||||
v-if="haveBack"
|
||||
:src="backUrl"
|
||||
class="pos-absolute left-3 h-5 w-5"
|
||||
@click="back"
|
||||
></image>
|
||||
<view class="flex flex-items-center">
|
||||
<view class="line-clamp-1 max-w-60 break-all">
|
||||
{{ title }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="pos-absolute right--3">
|
||||
<slot></slot>
|
||||
</view>
|
||||
<view
|
||||
v-if="rightButtonText"
|
||||
class="text-3.5 font-normal pos-absolute right-5"
|
||||
@click="rightButton"
|
||||
>
|
||||
{{ rightButtonText }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useBasicStore } from '@/store'
|
||||
import GetSystemInfoResult = UniNamespace.GetSystemInfoResult
|
||||
|
||||
const $basic = useBasicStore()
|
||||
|
||||
const systemInfo = ref<GetSystemInfoResult>(null)
|
||||
|
||||
defineProps({
|
||||
mini: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
haveBack: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
backUrl: {
|
||||
type: String,
|
||||
default: '/static/images/icon_back.png'
|
||||
},
|
||||
rightButtonText: {
|
||||
type: [String, null],
|
||||
default: null
|
||||
}
|
||||
})
|
||||
|
||||
const emits = defineEmits(['back', 'rightButton'])
|
||||
|
||||
const back = () => {
|
||||
uni.navigateBack()
|
||||
emits('back')
|
||||
}
|
||||
|
||||
const rightButton = () => {
|
||||
emits('rightButton')
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
systemInfo.value = await $basic.getSystemInfo()
|
||||
})
|
||||
</script>
|
||||
@ -1,5 +0,0 @@
|
||||
export const phoneRegExp: RegExp = /^1[3-9]\d{9}$/
|
||||
|
||||
export const passwordRegExp: RegExp = /^(?![0-9]+$)(?![a-zA-Z]+$)(?![^0-9a-zA-Z]+$).{8,20}$/
|
||||
|
||||
export const codeRegExp: RegExp = /^[0-9]{6}$/
|
||||
@ -1,64 +0,0 @@
|
||||
enum ResultCode {
|
||||
Success = 0,
|
||||
Fail = -1,
|
||||
NotMore = -2,
|
||||
PaySuccessful = 10003,
|
||||
NewDevice = 441
|
||||
}
|
||||
|
||||
interface ResultData {
|
||||
code: ResultCode
|
||||
data: Record<string, any>
|
||||
message: string
|
||||
}
|
||||
|
||||
export class Result {
|
||||
static resultsMap = new Map<ResultCode, Omit<ResultData, 'code'>>([
|
||||
[ResultCode.Success, { message: '成功', data: {} }],
|
||||
[ResultCode.Fail, { message: '网络加载失败', data: {} }],
|
||||
[ResultCode.NotMore, { message: '没有更多', data: {} }],
|
||||
[ResultCode.PaySuccessful, { message: '支付成功', data: {} }]
|
||||
])
|
||||
|
||||
code: ResultCode
|
||||
message: string
|
||||
data: Record<string, any>
|
||||
|
||||
constructor(code: ResultCode, data?: Record<string, any>, message?: string) {
|
||||
const result = Result.resultsMap.get(code)
|
||||
if (result) {
|
||||
this.code = code
|
||||
this.message = message || result.message
|
||||
this.data = data || result.data
|
||||
} else {
|
||||
this.code = code
|
||||
this.message = message || ''
|
||||
this.data = data || {}
|
||||
}
|
||||
}
|
||||
|
||||
// 成功
|
||||
static get Success(): Result {
|
||||
return new Result(ResultCode.Success)
|
||||
}
|
||||
|
||||
// 失败(默认错误)
|
||||
static get Fail(): Result {
|
||||
return new Result(ResultCode.Fail)
|
||||
}
|
||||
|
||||
// 没有更多
|
||||
static get NotMore(): Result {
|
||||
return new Result(ResultCode.NotMore)
|
||||
}
|
||||
|
||||
// 支付成功
|
||||
static get PaySuccessful(): Result {
|
||||
return new Result(ResultCode.PaySuccessful)
|
||||
}
|
||||
|
||||
// 新设备
|
||||
static get NewDevice(): Result {
|
||||
return new Result(ResultCode.NewDevice)
|
||||
}
|
||||
}
|
||||
31
src/env.d.ts
vendored
31
src/env.d.ts
vendored
@ -1,31 +0,0 @@
|
||||
/// <reference types="vite/client" />
|
||||
/// <reference types="vite-svg-loader" />
|
||||
|
||||
declare module '*.vue' {
|
||||
import { DefineComponent } from 'vue'
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
||||
|
||||
interface ImportMetaEnv {
|
||||
/** 网站标题,应用名称 */
|
||||
readonly VITE_APP_TITLE: string
|
||||
/** 服务端口号 */
|
||||
readonly VITE_SERVER_PORT: string
|
||||
/** 后台接口地址 */
|
||||
readonly VITE_SERVER_BASEURL: string
|
||||
/** H5是否需要代理 */
|
||||
readonly VITE_APP_PROXY: 'true' | 'false'
|
||||
/** H5是否需要代理,需要的话有个前缀 */
|
||||
readonly VITE_APP_PROXY_PREFIX: string // 一般是/api
|
||||
/** 上传图片地址 */
|
||||
readonly VITE_UPLOAD_BASEURL: string
|
||||
/** 是否清除console */
|
||||
readonly VITE_DELETE_CONSOLE: string
|
||||
// 更多环境变量...
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
import { UnwrapRef } from 'vue'
|
||||
import { IResData } from '@/typings'
|
||||
|
||||
type IUseRequestOptions<T> = {
|
||||
/** 是否立即执行 */
|
||||
immediate?: boolean
|
||||
/** 初始化数据 */
|
||||
initialData?: T
|
||||
}
|
||||
|
||||
/**
|
||||
* useRequest是一个定制化的请求钩子,用于处理异步请求和响应。
|
||||
* @param func 一个执行异步请求的函数,返回一个包含响应数据的Promise。
|
||||
* @param options 包含请求选项的对象 {immediate, initialData}。
|
||||
* @param options.immediate 是否立即执行请求,默认为false。
|
||||
* @param options.initialData 初始化数据,默认为undefined。
|
||||
* @returns 返回一个对象{loading, error, data, run},包含请求的加载状态、错误信息、响应数据和手动触发请求的函数。
|
||||
*/
|
||||
export default function useRequest<T>(
|
||||
func: () => Promise<IResData<T>>,
|
||||
options: IUseRequestOptions<T> = { immediate: false }
|
||||
) {
|
||||
const loading = ref(false)
|
||||
const error = ref(false)
|
||||
const data = ref<T>(options.initialData)
|
||||
const run = async () => {
|
||||
loading.value = true
|
||||
return func()
|
||||
.then(res => {
|
||||
data.value = res.data as UnwrapRef<T>
|
||||
error.value = false
|
||||
return data.value
|
||||
})
|
||||
.catch(err => {
|
||||
error.value = err
|
||||
throw err
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
options.immediate && run()
|
||||
return { loading, error, data, run }
|
||||
}
|
||||
@ -1,69 +0,0 @@
|
||||
// TODO: 别忘加更改环境变量的 VITE_UPLOAD_BASEURL 地址。
|
||||
import { getEnvBaseUploadUrl } from '@/utils'
|
||||
|
||||
const VITE_UPLOAD_BASEURL = `${getEnvBaseUploadUrl()}`
|
||||
|
||||
/**
|
||||
* useUpload 是一个定制化的请求钩子,用于处理上传图片。
|
||||
* @param formData 额外传递给后台的数据,如{name: '菲鸽'}。
|
||||
* @returns 返回一个对象{loading, error, data, run},包含请求的加载状态、错误信息、响应数据和手动触发请求的函数。
|
||||
*/
|
||||
export default function useUpload<T = string>(formData: Record<string, any> = {}) {
|
||||
const loading = ref(false)
|
||||
const error = ref(false)
|
||||
const data = ref<T>()
|
||||
const run = () => {
|
||||
// #ifdef MP-WEIXIN
|
||||
// 微信小程序从基础库 2.21.0 开始, wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替。
|
||||
// 微信小程序在2023年10月17日之后,使用本API需要配置隐私协议
|
||||
uni.chooseMedia({
|
||||
count: 1,
|
||||
mediaType: ['image'],
|
||||
success: res => {
|
||||
loading.value = true
|
||||
const tempFilePath = res.tempFiles[0].tempFilePath
|
||||
uploadFile<T>({ tempFilePath, formData, data, error, loading })
|
||||
},
|
||||
fail: err => {
|
||||
console.error('uni.chooseMedia err->', err)
|
||||
error.value = true
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
success: res => {
|
||||
loading.value = true
|
||||
const tempFilePath = res.tempFilePaths[0]
|
||||
uploadFile<T>({ tempFilePath, formData, data, error, loading })
|
||||
},
|
||||
fail: err => {
|
||||
console.error('uni.chooseImage err->', err)
|
||||
error.value = true
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
|
||||
return { loading, error, data, run }
|
||||
}
|
||||
|
||||
function uploadFile<T>({ tempFilePath, formData, data, error, loading }) {
|
||||
uni.uploadFile({
|
||||
url: VITE_UPLOAD_BASEURL,
|
||||
filePath: tempFilePath,
|
||||
name: 'file',
|
||||
formData,
|
||||
success: uploadFileRes => {
|
||||
data.value = uploadFileRes.data as T
|
||||
},
|
||||
fail: err => {
|
||||
console.error('uni.uploadFile err->', err)
|
||||
error.value = true
|
||||
},
|
||||
complete: () => {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
export { routeInterceptor } from './route'
|
||||
export { requestInterceptor } from './request'
|
||||
export { prototypeInterceptor } from './prototype'
|
||||
@ -1,13 +0,0 @@
|
||||
export const prototypeInterceptor = {
|
||||
install() {
|
||||
// 解决低版本手机不识别 array.at() 导致运行报错的问题
|
||||
if (typeof Array.prototype.at !== 'function') {
|
||||
// eslint-disable-next-line no-extend-native
|
||||
Array.prototype.at = function (index: number) {
|
||||
if (index < 0) return this[this.length + index]
|
||||
if (index >= this.length) return undefined
|
||||
return this[index]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,63 +0,0 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
import qs from 'qs'
|
||||
import { useUserStore } from '@/store'
|
||||
import { platform } from '@/utils/platform'
|
||||
import { getEnvBaseUrl } from '@/utils'
|
||||
|
||||
export type CustomRequestOptions = UniApp.RequestOptions & {
|
||||
query?: Record<string, any>
|
||||
/** 出错时是否隐藏错误提示 */
|
||||
hideErrorToast?: boolean
|
||||
} & IUniUploadFileOptions // 添加uni.uploadFile参数类型
|
||||
|
||||
// 请求基准地址
|
||||
const baseUrl = getEnvBaseUrl()
|
||||
|
||||
// 拦截器配置
|
||||
const httpInterceptor = {
|
||||
// 拦截前触发
|
||||
invoke(options: CustomRequestOptions) {
|
||||
if (options.query) {
|
||||
const queryStr = qs.stringify(options.query)
|
||||
if (options.url.includes('?')) {
|
||||
options.url += `&${queryStr}`
|
||||
} else {
|
||||
options.url += `?${queryStr}`
|
||||
}
|
||||
}
|
||||
if (!options.url.startsWith('http')) {
|
||||
// #ifdef H5
|
||||
// console.log(__VITE_APP_PROXY__)
|
||||
if (JSON.parse(__VITE_APP_PROXY__)) {
|
||||
// 啥都不需要做
|
||||
} else {
|
||||
options.url = baseUrl + options.url
|
||||
}
|
||||
// #endif
|
||||
// 非H5正常拼接
|
||||
// #ifndef H5
|
||||
options.url = baseUrl + options.url
|
||||
// #endif
|
||||
// TIPS: 如果需要对接多个后端服务,也可以在这里处理,拼接成所需要的地址
|
||||
}
|
||||
options.timeout = 3000
|
||||
options.header = {
|
||||
platform,
|
||||
version: import.meta.env.VITE_APP_VERSION + '+' + import.meta.env.VITE_APP_BUILD_NUMBER,
|
||||
...options.header
|
||||
}
|
||||
const token = uni.getStorageSync('token')
|
||||
if (token) {
|
||||
options.header.Authorization = `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const requestInterceptor = {
|
||||
install() {
|
||||
// 拦截 request 请求
|
||||
uni.addInterceptor('request', httpInterceptor)
|
||||
// 拦截 uploadFile 文件上传
|
||||
uni.addInterceptor('uploadFile', httpInterceptor)
|
||||
}
|
||||
}
|
||||
@ -1,46 +0,0 @@
|
||||
/**
|
||||
* 路由拦截,通常也是登录拦截
|
||||
* 可以设置路由白名单,或者黑名单,看业务需要选哪一个
|
||||
* 我这里应为大部分都可以随便进入,所以使用黑名单
|
||||
*/
|
||||
import { useUserStore } from '@/store'
|
||||
import { getNeedLoginPages, needLoginPages as _needLoginPages } from '@/utils'
|
||||
|
||||
const loginRoute = '/pages/login/login'
|
||||
|
||||
const loginStatus = () => {
|
||||
const userStore = useUserStore()
|
||||
return userStore.loginStatus
|
||||
}
|
||||
|
||||
const isDev = import.meta.env.DEV
|
||||
|
||||
const navigateToInterceptor = {
|
||||
invoke({ url }: { url: string }) {
|
||||
const path = url.split('?')[0]
|
||||
let needLoginPages: string[] = []
|
||||
if (isDev) {
|
||||
needLoginPages = getNeedLoginPages()
|
||||
} else {
|
||||
needLoginPages = _needLoginPages
|
||||
}
|
||||
const isNeedLogin = needLoginPages.includes(path)
|
||||
if (!isNeedLogin) {
|
||||
return true
|
||||
}
|
||||
const hasLogin = loginStatus()
|
||||
if (hasLogin) {
|
||||
return true
|
||||
}
|
||||
uni.navigateTo({ url: loginRoute })
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export const routeInterceptor = {
|
||||
install() {
|
||||
uni.addInterceptor('navigateTo', navigateToInterceptor)
|
||||
uni.addInterceptor('reLaunch', navigateToInterceptor)
|
||||
uni.addInterceptor('redirectTo', navigateToInterceptor)
|
||||
}
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
<template>
|
||||
<wd-config-provider :themeVars="themeVars">
|
||||
<slot />
|
||||
<wd-toast />
|
||||
<wd-message-box />
|
||||
</wd-config-provider>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { ConfigProviderThemeVars } from 'wot-design-uni'
|
||||
|
||||
const themeVars: ConfigProviderThemeVars = {
|
||||
// colorTheme: 'red',
|
||||
// buttonPrimaryBgColor: '#07c160',
|
||||
// buttonPrimaryColor: '#07c160',
|
||||
}
|
||||
</script>
|
||||
@ -1,17 +0,0 @@
|
||||
<template>
|
||||
<wd-config-provider :themeVars="themeVars">
|
||||
<slot />
|
||||
<wd-toast />
|
||||
<wd-message-box />
|
||||
</wd-config-provider>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { ConfigProviderThemeVars } from 'wot-design-uni'
|
||||
|
||||
const themeVars: ConfigProviderThemeVars = {
|
||||
// colorTheme: 'red',
|
||||
// buttonPrimaryBgColor: '#07c160',
|
||||
// buttonPrimaryColor: '#07c160',
|
||||
}
|
||||
</script>
|
||||
17
src/main.ts
17
src/main.ts
@ -1,17 +0,0 @@
|
||||
import { createSSRApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import store from './store'
|
||||
import { routeInterceptor, requestInterceptor, prototypeInterceptor } from './interceptors'
|
||||
import 'virtual:uno.css'
|
||||
import '@/style/index.scss'
|
||||
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App)
|
||||
app.use(store)
|
||||
app.use(routeInterceptor)
|
||||
app.use(requestInterceptor)
|
||||
app.use(prototypeInterceptor)
|
||||
return {
|
||||
app
|
||||
}
|
||||
}
|
||||
@ -1,111 +0,0 @@
|
||||
{
|
||||
"name": "星星勤务",
|
||||
"appid": "__UNI__58536F2",
|
||||
"description": "",
|
||||
"versionName": "1.0.0",
|
||||
"versionCode": "100",
|
||||
"transformPx": false,
|
||||
"app-plus": {
|
||||
"usingComponents": true,
|
||||
"nvueStyleCompiler": "uni-app",
|
||||
"compilerVersion": 3,
|
||||
"splashscreen": {
|
||||
"alwaysShowBeforeRender": true,
|
||||
"waiting": true,
|
||||
"autoclose": true,
|
||||
"delay": 0
|
||||
},
|
||||
"modules": {},
|
||||
"distribute": {
|
||||
"android": {
|
||||
"permissions": [
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
],
|
||||
"minSdkVersion": 29,
|
||||
"targetSdkVersion": 30,
|
||||
"abiFilters": [
|
||||
"armeabi-v7a",
|
||||
"arm64-v8a"
|
||||
]
|
||||
},
|
||||
"ios": {},
|
||||
"sdkConfigs": {},
|
||||
"icons": {
|
||||
"android": {
|
||||
"hdpi": "static/app/icons/72x72.png",
|
||||
"xhdpi": "static/app/icons/96x96.png",
|
||||
"xxhdpi": "static/app/icons/144x144.png",
|
||||
"xxxhdpi": "static/app/icons/192x192.png"
|
||||
},
|
||||
"ios": {
|
||||
"appstore": "static/app/icons/1024x1024.png",
|
||||
"ipad": {
|
||||
"app": "static/app/icons/76x76.png",
|
||||
"app@2x": "static/app/icons/152x152.png",
|
||||
"notification": "static/app/icons/20x20.png",
|
||||
"notification@2x": "static/app/icons/40x40.png",
|
||||
"proapp@2x": "static/app/icons/167x167.png",
|
||||
"settings": "static/app/icons/29x29.png",
|
||||
"settings@2x": "static/app/icons/58x58.png",
|
||||
"spotlight": "static/app/icons/40x40.png",
|
||||
"spotlight@2x": "static/app/icons/80x80.png"
|
||||
},
|
||||
"iphone": {
|
||||
"app@2x": "static/app/icons/120x120.png",
|
||||
"app@3x": "static/app/icons/180x180.png",
|
||||
"notification@2x": "static/app/icons/40x40.png",
|
||||
"notification@3x": "static/app/icons/60x60.png",
|
||||
"settings@2x": "static/app/icons/58x58.png",
|
||||
"settings@3x": "static/app/icons/87x87.png",
|
||||
"spotlight@2x": "static/app/icons/80x80.png",
|
||||
"spotlight@3x": "static/app/icons/120x120.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"compatible": {
|
||||
"ignoreVersion": true
|
||||
}
|
||||
},
|
||||
"quickapp": {},
|
||||
"mp-weixin": {
|
||||
"appid": "wxa2abb91f64032a2b",
|
||||
"setting": {
|
||||
"urlCheck": false
|
||||
},
|
||||
"usingComponents": true
|
||||
},
|
||||
"mp-alipay": {
|
||||
"usingComponents": true,
|
||||
"styleIsolation": "shared"
|
||||
},
|
||||
"mp-baidu": {
|
||||
"usingComponents": true
|
||||
},
|
||||
"mp-toutiao": {
|
||||
"usingComponents": true
|
||||
},
|
||||
"uniStatistics": {
|
||||
"enable": false
|
||||
},
|
||||
"vueVersion": "3",
|
||||
"h5": {
|
||||
"router": {
|
||||
"base": "/"
|
||||
}
|
||||
}
|
||||
}
|
||||
520
src/pages.json
520
src/pages.json
@ -1,520 +0,0 @@
|
||||
{
|
||||
"globalStyle": {
|
||||
"navigationStyle": "default",
|
||||
"navigationBarTitleText": "星星勤务",
|
||||
"navigationBarBackgroundColor": "#f8f8f8",
|
||||
"navigationBarTextStyle": "black",
|
||||
"backgroundColor": "#FFFFFF"
|
||||
},
|
||||
"easycom": {
|
||||
"autoscan": true,
|
||||
"custom": {
|
||||
"^wd-(.*)": "wot-design-uni/components/wd-$1/wd-$1.vue",
|
||||
"^(?!z-paging-refresh|z-paging-load-more)z-paging(.*)": "z-paging/components/z-paging$1/z-paging$1.vue"
|
||||
}
|
||||
},
|
||||
"tabBar": {
|
||||
"color": "#0d0f10",
|
||||
"selectedColor": "#255cf7",
|
||||
"backgroundColor": "#FFFFFF",
|
||||
"borderStyle": "black",
|
||||
"height": "50px",
|
||||
"fontSize": "10px",
|
||||
"iconWidth": "24px",
|
||||
"spacing": "5px",
|
||||
"list": [
|
||||
{
|
||||
"iconPath": "static/tabbar/home.png",
|
||||
"selectedIconPath": "static/tabbar/home_selected.png",
|
||||
"pagePath": "pages/home/home",
|
||||
"text": "首页"
|
||||
},
|
||||
{
|
||||
"iconPath": "static/tabbar/workbench.png",
|
||||
"selectedIconPath": "static/tabbar/workbench_selected.png",
|
||||
"pagePath": "pages/workbench/workbench",
|
||||
"text": "工作台"
|
||||
},
|
||||
{
|
||||
"iconPath": "static/tabbar/notification.png",
|
||||
"selectedIconPath": "static/tabbar/notification_selected.png",
|
||||
"pagePath": "pages/notification/notification",
|
||||
"text": "消息"
|
||||
},
|
||||
{
|
||||
"iconPath": "static/tabbar/mine.png",
|
||||
"selectedIconPath": "static/tabbar/mine_selected.png",
|
||||
"pagePath": "pages/mine/mine",
|
||||
"text": "我的"
|
||||
}
|
||||
]
|
||||
},
|
||||
"pages": [
|
||||
{
|
||||
"path": "pages/home/home",
|
||||
"type": "home",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "首页",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/approval/approval-detail",
|
||||
"type": "page",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/approval/approval-result",
|
||||
"type": "page",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/approval/approval",
|
||||
"type": "page",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/approval/create-application",
|
||||
"type": "page",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/attendance/allowed-time",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/attendance/attendance-rules",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/attendance/attendance",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/attendance/classes-add-edit",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/attendance/classes-manage",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/attendance/flexible-punching",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/attendance/issue-record-detail",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/attendance/issue-record",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/home/application-list",
|
||||
"type": "page"
|
||||
},
|
||||
{
|
||||
"path": "pages/info-publish/add-release-plan",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/info-publish/announce-notice",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/info-publish/basic-info",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/info-publish/drafts-list",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/info-publish/edit-pic-video",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/info-publish/info-publish",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/info-publish/material-library",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/info-publish/notice-details",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/info-publish/notice-manage",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/info-publish/play-content-library",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/info-publish/release-plan",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/code",
|
||||
"type": "page",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"disableScroll": true
|
||||
},
|
||||
"needLogin": false
|
||||
},
|
||||
{
|
||||
"path": "pages/login/get-code",
|
||||
"type": "page",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"disableScroll": true
|
||||
},
|
||||
"needLogin": false
|
||||
},
|
||||
{
|
||||
"path": "pages/login/login",
|
||||
"type": "page",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"disableScroll": true
|
||||
},
|
||||
"needLogin": false
|
||||
},
|
||||
{
|
||||
"path": "pages/login/reset-password",
|
||||
"type": "page",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"disableScroll": true
|
||||
},
|
||||
"needLogin": false
|
||||
},
|
||||
{
|
||||
"path": "pages/mine/mine",
|
||||
"type": "page",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/notification/notification",
|
||||
"type": "page"
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/traffic-correlation",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/select/select-access-control",
|
||||
"type": "page",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/select/select-organization",
|
||||
"type": "page",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/workbench/workbench",
|
||||
"type": "page"
|
||||
},
|
||||
{
|
||||
"path": "pages/attendance/attendance-add-group/attendance-add-group",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/attendance/attendance-add-group/attendance-device",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/attendance/attendance-add-group/attendance-staff",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/attendance/attendance-add-group/attendance-time",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/attendance/attendance-add-group/outside-rules",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/attendance/attendance-add-group/special-date-set",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/access-permission-inquiry",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/access-right-detection",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/add-permission-group",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/delivery-status",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/permission-query",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/release-record",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/send-permission",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/viewing-delivery-records",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"disableScroll": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/access-authority/access-authority",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/one-click-open-door/one-click-open-door",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/password-open-door/password-open-door",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/traffic-record/traffic-record",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/visitor-invitation/visitor-invitation",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/visitor-manage/visitor-manage-tab",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/time-planning-allocation/add-daily-traffic-plan",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/time-planning-allocation/add-time-schedule",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/time-planning-allocation/time-planning-allocation-detail",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/personnel-passage/AccessManage/time-planning-allocation/time-planning-allocation-list",
|
||||
"type": "page",
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
}
|
||||
],
|
||||
"subPackages": []
|
||||
}
|
||||
@ -1,75 +0,0 @@
|
||||
<route lang="json5">
|
||||
{
|
||||
style: {
|
||||
navigationStyle: 'custom',
|
||||
disableScroll: true
|
||||
}
|
||||
}
|
||||
</route>
|
||||
<template>
|
||||
<view class="h-100vh flex flex-col">
|
||||
<TopNavigation title="详情"></TopNavigation>
|
||||
<scroll-view class="flex-1 box-border" :scroll-y="true">
|
||||
<view class="pb-5">
|
||||
<ApprovalContent class="mt-2" />
|
||||
<ApprovalProcess class="mt-2" />
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="pb-safe border-#eef0f5 border-t-solid">
|
||||
<view class="flex flex-items-center flex-justify-around py-3">
|
||||
<view class="py-2 px-13 bg-#ef2e2f color-white rounded-2" @click="toResult('reject')">
|
||||
拒绝
|
||||
</view>
|
||||
<view class="py-2 px-13 custom-bg-blue color-white rounded-2" @click="toResult('agree')">
|
||||
同意
|
||||
</view>
|
||||
<view class="custom-color-blue text-4" @click="showActions">更多</view>
|
||||
</view>
|
||||
</view>
|
||||
<wd-action-sheet
|
||||
v-model="show"
|
||||
:actions="actions"
|
||||
close-on-click-action
|
||||
@close="close"
|
||||
@select="select"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import ApprovalContent from '@/pages/approval/components/ApprovalContent.vue'
|
||||
import ApprovalProcess from '@/pages/approval/components/ApprovalProcess.vue'
|
||||
|
||||
const show = ref<boolean>(false)
|
||||
const actions = ref([
|
||||
{
|
||||
name: '转审',
|
||||
type: 'transfer'
|
||||
},
|
||||
{
|
||||
name: '退回',
|
||||
type: 'return'
|
||||
},
|
||||
{
|
||||
name: '取消'
|
||||
}
|
||||
])
|
||||
|
||||
const showActions = () => {
|
||||
show.value = true
|
||||
}
|
||||
|
||||
const close = () => {
|
||||
show.value = false
|
||||
}
|
||||
|
||||
const select = ({ item }) => {
|
||||
toResult(item.type)
|
||||
}
|
||||
|
||||
const toResult = type => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/approval/approval-result?type=${type}`
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@ -1,95 +0,0 @@
|
||||
<route lang="json5">
|
||||
{
|
||||
style: {
|
||||
navigationStyle: 'custom',
|
||||
disableScroll: true
|
||||
}
|
||||
}
|
||||
</route>
|
||||
<template>
|
||||
<view>
|
||||
<TopNavigation :title="textMap[type].title"></TopNavigation>
|
||||
<view v-if="type === 'transfer'" class="bg-white mx-4 px-4 py-2 rounded-2 shadow-sm text-3.5">
|
||||
<view class="flex flex-items-center pos-relative">
|
||||
<view class="color-#ee322a mt-1.5 pos-absolute left--2">*</view>
|
||||
<view>转审人</view>
|
||||
</view>
|
||||
<view class="mb-2 w-fit mr-2 mt-4">
|
||||
<view
|
||||
class="h-10 w-10 rounded-2 border-#255cf7 border-1 border-solid flex flex-items-center flex-justify-center box-border"
|
||||
>
|
||||
<wd-icon name="add" size="22px" color="#255cf7"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="type === 'return'" class="bg-white mx-4 px-4 py-2 rounded-2 shadow-sm text-3.5">
|
||||
<view class="flex flex-items-center pos-relative">
|
||||
<view class="color-#ee322a mt-1.5 pos-absolute left--2">*</view>
|
||||
<view>退回至</view>
|
||||
</view>
|
||||
<view class="color-#838589 text-3 mt-2">选择退回节点,对方处理后,将按原有流程重新审批</view>
|
||||
<view class="flex flex-items-center mt-2">
|
||||
<view class="custom-bg-blue w-5 h-5 rounded-50% flex flex-items-center flex-justify-center">
|
||||
<view class="w-2.5 h-2.5 bg-white rounded-50%"></view>
|
||||
</view>
|
||||
<view class="ml-2">发起人</view>
|
||||
</view>
|
||||
<view class="ml-7 mt-2 mb-2 py-1 flex flex-items-center w-fit rounded-4 bg-#f3f5fa">
|
||||
<image
|
||||
src="https://file.hikmall.com/prod/image/4921b7596d2344088f8611f503b011dc.png"
|
||||
class="h-6 w-6 rounded-50%"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="mx-2">xxx</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bg-white mx-4 p-2 rounded-2 shadow-sm mt-2">
|
||||
<Textarea
|
||||
:id="0"
|
||||
:title="textMap[type].placeholder"
|
||||
:required="false"
|
||||
placeholder="请输入(选填)"
|
||||
@change="textareaChange"
|
||||
></Textarea>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// agree reject return transfer
|
||||
import Textarea from '@/pages/approval/components/Textarea.vue'
|
||||
|
||||
const type = ref<string>('agree')
|
||||
const approvalType = ref<string>('请假')
|
||||
|
||||
const textMap = {
|
||||
agree: {
|
||||
title: '审批意见',
|
||||
placeholder: `确认同意${approvalType.value}申请`
|
||||
},
|
||||
reject: {
|
||||
title: '审批意见',
|
||||
placeholder: `确认拒绝${approvalType.value}申请`
|
||||
},
|
||||
return: {
|
||||
title: '退回',
|
||||
placeholder: `退回原因`
|
||||
},
|
||||
transfer: {
|
||||
title: '转审',
|
||||
placeholder: `转审原因`
|
||||
}
|
||||
}
|
||||
|
||||
onLoad(options => {
|
||||
if (options.type) {
|
||||
type.value = options.type
|
||||
}
|
||||
})
|
||||
|
||||
const textareaChange = e => {
|
||||
console.log('textareaChange', e)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -1,119 +0,0 @@
|
||||
<route lang="json5">
|
||||
{
|
||||
style: {
|
||||
navigationStyle: 'custom',
|
||||
disableScroll: true
|
||||
}
|
||||
}
|
||||
</route>
|
||||
<template>
|
||||
<view class="h-100vh flex flex-col">
|
||||
<TopNavigation :title="index === 0 ? '发起申请' : '审批'"></TopNavigation>
|
||||
<ApplicationList v-show="index === 0" :list="applicationListData"></ApplicationList>
|
||||
<view v-show="index === 1" class="flex-1 box-border">
|
||||
<ApprovalRecords></ApprovalRecords>
|
||||
</view>
|
||||
<CustomTabBar :list="list" :default-index="index" @change="change"></CustomTabBar>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { TabBarItem } from '@/typings'
|
||||
import ApplicationList from '@/pages/approval/components/ApplicationList.vue'
|
||||
import ApprovalRecords from '@/pages/approval/components/ApprovalRecords.vue'
|
||||
|
||||
const index = ref<number>(0)
|
||||
|
||||
const list: Array<TabBarItem> = [
|
||||
{
|
||||
title: '新申请',
|
||||
icon: 'home'
|
||||
},
|
||||
{
|
||||
title: '审批中心',
|
||||
icon: 'home'
|
||||
}
|
||||
]
|
||||
|
||||
const applicationListData = ref<Array<object>>([
|
||||
{
|
||||
groupId: 138603,
|
||||
groupName: '出勤休假',
|
||||
sort: 1,
|
||||
processDefs: [
|
||||
{
|
||||
processDefId: 249155,
|
||||
processDefName: '请假',
|
||||
icon: 'https://file.hikvisionmall.com/test1/image/f39c654cd30a48d28ddf37e4b64de57a.png',
|
||||
version: '1735128632'
|
||||
},
|
||||
{
|
||||
processDefId: 249156,
|
||||
processDefName: '补卡',
|
||||
icon: 'https://file.hikvisionmall.com/test1/image/26209b6732f2439fae3c6dd34a39145e.png',
|
||||
version: '1704439843'
|
||||
},
|
||||
{
|
||||
processDefId: 249158,
|
||||
processDefName: '外出',
|
||||
icon: 'https://file.hikvisionmall.com/test1/image/5c76288745dd47a38c9e1093d9737976.png',
|
||||
version: '1704439843'
|
||||
},
|
||||
{
|
||||
processDefId: 249157,
|
||||
processDefName: '出差',
|
||||
icon: 'https://file.hikvisionmall.com/test1/image/df75579e70c2435e9f78d04fc401b451.png',
|
||||
version: '1704439843'
|
||||
},
|
||||
{
|
||||
processDefId: 347336,
|
||||
processDefName: '加班',
|
||||
icon: 'https://file.hikvisionmall.com/test1/image/e4f21377ea2443b3856b07674ba41c2a.png',
|
||||
version: '1711368134'
|
||||
},
|
||||
{
|
||||
processDefId: 891737,
|
||||
processDefName: '调休',
|
||||
icon: 'https://file.hikvisionmall.com/prod/image/3d134cc9657e4816ad6aa8ef206fbc89.png',
|
||||
version: '1735128832'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
groupId: 341473,
|
||||
groupName: 'test',
|
||||
sort: 2,
|
||||
processDefs: [
|
||||
{
|
||||
processDefId: 924255,
|
||||
processDefName: 'test1',
|
||||
icon: 'https://file.hikvisionmall.com/prod/image/3d134cc9657e4816ad6aa8ef206fbc89.png',
|
||||
version: '1736480449'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
groupId: 138604,
|
||||
groupName: '其他',
|
||||
sort: 999,
|
||||
processDefs: [
|
||||
{
|
||||
processDefId: 466818,
|
||||
processDefName: '访客预约',
|
||||
icon: 'https://file.hikmall.com/prod/image/5300a838119d462b9e1c17489603b6d8.png',
|
||||
version: '1715675086'
|
||||
}
|
||||
]
|
||||
}
|
||||
])
|
||||
|
||||
onLoad(options => {
|
||||
if (options.index) {
|
||||
index.value = Number(options.index)
|
||||
}
|
||||
})
|
||||
|
||||
const change = (data: object) => {
|
||||
index.value = data.value
|
||||
}
|
||||
</script>
|
||||
@ -1,65 +0,0 @@
|
||||
<template>
|
||||
<scroll-view class="flex-1 box-border" :scroll-y="true">
|
||||
<view class="mx-4 pt-4 flex flex-items-center text-3.5 font-bold">
|
||||
<view class="bg-#dfecff flex-1 px-3 py-6 rounded-2">
|
||||
<view>使用指南</view>
|
||||
</view>
|
||||
<view class="w-4"></view>
|
||||
<view class="bg-#feebda flex-1 px-3 py-6 rounded-2">
|
||||
<view>常见问题</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="py-4">
|
||||
<wd-collapse v-model="collapseRoot" custom-class="!bg-transparent !border-0">
|
||||
<wd-collapse-item
|
||||
v-for="group in list"
|
||||
:key="group.groupId"
|
||||
:name="group.groupName"
|
||||
:title="group.groupName"
|
||||
>
|
||||
<view
|
||||
v-for="(item, index) in group.processDefs"
|
||||
:key="item.processDefId"
|
||||
:class="[index === group.processDefs.length - 1 ? '' : 'mb-2']"
|
||||
class="flex flex-items-center bg-white px-3 py-3 mx-1 rounded-2"
|
||||
@click="toDetail(item)"
|
||||
>
|
||||
<image :src="item.icon" class="w-7 h-7 rounded-2"></image>
|
||||
<view class="text-3.5 ml-2">{{ item.processDefName }}</view>
|
||||
</view>
|
||||
</wd-collapse-item>
|
||||
</wd-collapse>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const collapseRoot = ref<string[]>([])
|
||||
|
||||
onMounted(() => {
|
||||
collapseRoot.value = props.list.map(item => item.groupName)
|
||||
})
|
||||
|
||||
const props = defineProps({
|
||||
list: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const toDetail = (item: Record<string, any>) => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/approval/create-application?id=${item.processDefId}&title=${item.processDefName}`
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wd-collapse-item::after {
|
||||
height: 0 !important;
|
||||
}
|
||||
|
||||
:deep(.wd-collapse-item__header::after) {
|
||||
height: 0 !important;
|
||||
}
|
||||
</style>
|
||||
@ -1,61 +0,0 @@
|
||||
<template>
|
||||
<view class="bg-white rounded-2 py-2 px-4 mx-4">
|
||||
<view class="flex flex-items-center">
|
||||
<image
|
||||
src="/static/images/icon_default_avatar.png"
|
||||
class="w-10 h-10"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="ml-4">
|
||||
<view class="font-bold text-4.5">请假</view>
|
||||
<view class="text-3.5 mt-1">xxx</view>
|
||||
</view>
|
||||
<view
|
||||
class="ml-a rounded py-0.5 px-1.5 text-3.5 border-solid border-1 border-#ef811c color-#ef811c"
|
||||
>
|
||||
审批中
|
||||
</view>
|
||||
</view>
|
||||
<view class="my-2 h-1px w-full bg-#eef0f5"></view>
|
||||
<view class="custom-color-black">
|
||||
<view>所属组织:</view>
|
||||
<view class="mt-2 break-all">123132123的互联</view>
|
||||
</view>
|
||||
<view class="my-2 h-1px w-full bg-#eef0f5"></view>
|
||||
<view class="custom-color-black">
|
||||
<view>审批编号:</view>
|
||||
<view class="mt-2 break-all">845465465465465465456</view>
|
||||
</view>
|
||||
<view class="my-2 h-1px w-full bg-#eef0f5"></view>
|
||||
<view class="custom-color-black">
|
||||
<view>请假类型:</view>
|
||||
<view class="mt-2 break-all">年假</view>
|
||||
</view>
|
||||
<view class="my-2 h-1px w-full bg-#eef0f5"></view>
|
||||
<view class="custom-color-black">
|
||||
<view>开始时间:</view>
|
||||
<view class="mt-2 break-all">2025-01-10</view>
|
||||
</view>
|
||||
<view class="my-2 h-1px w-full bg-#eef0f5"></view>
|
||||
<view class="custom-color-black">
|
||||
<view>结束时间:</view>
|
||||
<view class="mt-2 break-all">2025-01-10</view>
|
||||
</view>
|
||||
<view class="my-2 h-1px w-full bg-#eef0f5"></view>
|
||||
<view class="custom-color-black">
|
||||
<view>请假时长(天):</view>
|
||||
<view class="mt-2 break-all">1.0</view>
|
||||
</view>
|
||||
<view class="my-2 h-1px w-full bg-#eef0f5"></view>
|
||||
<view class="custom-color-black">
|
||||
<view>请假原因:</view>
|
||||
<view class="mt-2 break-all">
|
||||
请假请假请假请假请假请假请假请假请假请假请假请假请假请假请假请假请假请假请假请假请假请假请假请假请假请假请假1111111111111111111111
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -1,155 +0,0 @@
|
||||
<template>
|
||||
<view class="bg-white rounded-2 py-3 px-4 mx-4 my-2 shadow-sm">
|
||||
<view class="text-4">审批流程</view>
|
||||
<view v-if="false" class="text-3 color-#838589 mt-2">必填信息填写完整后,将显示审批流程</view>
|
||||
<view v-else class="mt-4 color-#838589">
|
||||
<wd-steps :active="3" vertical>
|
||||
<wd-step>
|
||||
<template v-slot:icon>
|
||||
<view
|
||||
class="custom-bg-blue w-5 h-5 rounded-50% flex flex-items-center flex-justify-center"
|
||||
>
|
||||
<view class="w-2.5 h-2.5 bg-white rounded-50%"></view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-slot:title>
|
||||
<view class="custom-color-black text-3.5">
|
||||
<view class="flex-items-center flex">
|
||||
<view>发起人</view>
|
||||
</view>
|
||||
<view class="my-2">
|
||||
<view>
|
||||
<image
|
||||
src="https://file.hikmall.com/prod/image/4921b7596d2344088f8611f503b011dc.png"
|
||||
class="h-10 w-10 rounded-2"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view
|
||||
class="w-10 text-center break-all overflow-hidden text-ellipsis line-clamp-1"
|
||||
>
|
||||
213321123321312213321123
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</wd-step>
|
||||
<wd-step>
|
||||
<template v-slot:icon>
|
||||
<view class="bg-#f0801e w-5 h-5 rounded-50% flex flex-items-center flex-justify-center">
|
||||
<image src="/static/images/icon_approval.png" class="w-3 h-3"></image>
|
||||
</view>
|
||||
</template>
|
||||
<template v-slot:title>
|
||||
<view class="custom-color-black text-3.5">
|
||||
<view class="flex-items-center flex">
|
||||
<view>审批节点</view>
|
||||
</view>
|
||||
<view class="pt-2 color-#7e807f text-3">1人通过即可</view>
|
||||
<view class="my-2 flex flex-wrap">
|
||||
<view class="mb-2 w-fit mr-2">
|
||||
<view
|
||||
class="h-10 w-10 rounded-2 border-#255cf7 border-1 border-solid flex flex-items-center flex-justify-center box-border"
|
||||
>
|
||||
<wd-icon name="add" size="22px" color="#255cf7"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view v-for="item in 8" :key="item" class="mb-2 w-fit mr-2">
|
||||
<view class="border-0">
|
||||
<image
|
||||
src="https://file.hikmall.com/prod/image/4921b7596d2344088f8611f503b011dc.png"
|
||||
class="h-10 w-10 rounded-2"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view
|
||||
class="w-10 text-center break-all overflow-hidden text-ellipsis line-clamp-1"
|
||||
>
|
||||
xxx
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</wd-step>
|
||||
<wd-step>
|
||||
<template v-slot:icon>
|
||||
<view class="bg-#f0801e w-5 h-5 rounded-50% flex flex-items-center flex-justify-center">
|
||||
<image src="/static/images/icon_approval.png" class="w-3 h-3"></image>
|
||||
</view>
|
||||
</template>
|
||||
<template v-slot:title>
|
||||
<view class="custom-color-black text-3.5">
|
||||
<view class="flex-items-center flex">
|
||||
<view>审批节点</view>
|
||||
</view>
|
||||
<view class="pt-2 color-#7e807f text-3">1人通过即可</view>
|
||||
<view class="my-2 flex flex-wrap">
|
||||
<view v-for="item in 8" :key="item" class="mb-2 w-fit mr-2">
|
||||
<view>
|
||||
<image
|
||||
src="https://file.hikmall.com/prod/image/4921b7596d2344088f8611f503b011dc.png"
|
||||
class="h-10 w-10 rounded-2"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view
|
||||
class="w-10 text-center break-all overflow-hidden text-ellipsis line-clamp-1"
|
||||
>
|
||||
xxx
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</wd-step>
|
||||
<wd-step>
|
||||
<template v-slot:icon>
|
||||
<view class="bg-#2ab6c7 w-5 h-5 rounded-50% flex flex-items-center flex-justify-center">
|
||||
<image src="/static/images/icon_airplane.png" class="w-3 h-3"></image>
|
||||
</view>
|
||||
</template>
|
||||
<template v-slot:title>
|
||||
<view class="custom-color-black text-3.5">
|
||||
<view class="flex-items-center flex">
|
||||
<view>抄送节点</view>
|
||||
</view>
|
||||
<view class="my-2 flex flex-wrap">
|
||||
<view v-for="item in 3" :key="item" class="mb-2 w-fit mr-2">
|
||||
<view>
|
||||
<image
|
||||
src="https://file.hikmall.com/prod/image/4921b7596d2344088f8611f503b011dc.png"
|
||||
class="h-10 w-10 rounded-2"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view
|
||||
class="w-10 text-center break-all overflow-hidden text-ellipsis line-clamp-1"
|
||||
>
|
||||
xxx
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</wd-step>
|
||||
</wd-steps>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.wd-step__header) {
|
||||
width: 1.25rem;
|
||||
}
|
||||
|
||||
:deep(.wd-step__line) {
|
||||
background: #255cf7;
|
||||
}
|
||||
|
||||
:deep(.wd-step.is-vertical .wd-step__content) {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
@ -1,81 +0,0 @@
|
||||
<template>
|
||||
<view class="bg-white rounded-2 py-2 px-4 mx-4">
|
||||
<view class="py-2 text-4">审批流程</view>
|
||||
<wd-steps :active="1" vertical>
|
||||
<wd-step icon="link">
|
||||
<template v-slot:title>
|
||||
<view class="custom-color-black text-3.5">
|
||||
<view class="flex-items-center flex">
|
||||
<view>发起申请</view>
|
||||
<view class="ml-a color-#7e807f text-3">2504-12-25 20:11</view>
|
||||
</view>
|
||||
<view class="my-2">
|
||||
<view class="py-1 flex flex-items-center w-fit rounded-4 bg-#f3f5fa">
|
||||
<image
|
||||
src="/static/images/icon_default_avatar.png"
|
||||
class="h-6 w-6 rounded-50%"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="mx-2">xxx</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</wd-step>
|
||||
<wd-step icon="link">
|
||||
<template v-slot:title>
|
||||
<view class="custom-color-black text-3.5">
|
||||
<view class="flex-items-center flex">
|
||||
<view>审批节点</view>
|
||||
<view
|
||||
class="ml-3 rounded-4 py-0.5 text-3 px-2 border-solid border-#ef811c border-1 color-#ef811c"
|
||||
>
|
||||
审批中
|
||||
</view>
|
||||
</view>
|
||||
<view class="pt-2 color-#7e807f text-3">1人通过即可</view>
|
||||
<view class="my-2">
|
||||
<view
|
||||
v-for="item in 4"
|
||||
:key="item"
|
||||
class="mb-2 py-1 flex flex-items-center w-fit rounded-4 bg-#f3f5fa"
|
||||
>
|
||||
<image
|
||||
src="/static/images/icon_default_avatar.png"
|
||||
class="h-6 w-6 rounded-50%"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="mx-2">xxx</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</wd-step>
|
||||
<wd-step icon="link">
|
||||
<template v-slot:title>
|
||||
<view class="custom-color-black text-3.5">
|
||||
<view class="flex-items-center flex">
|
||||
<view>抄送节点</view>
|
||||
</view>
|
||||
<view class="my-2">
|
||||
<view
|
||||
v-for="item in 4"
|
||||
:key="item"
|
||||
class="mb-2 py-1 flex flex-items-center w-fit rounded-4 bg-#f3f5fa"
|
||||
>
|
||||
<image
|
||||
src="/static/images/icon_default_avatar.png"
|
||||
class="h-6 w-6 rounded-50%"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="mx-2">xxx</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</wd-step>
|
||||
</wd-steps>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
@ -1,158 +0,0 @@
|
||||
<template>
|
||||
<view class="mx-4 mt-2">
|
||||
<wd-input
|
||||
class="px-2 py-0.6 rounded-1"
|
||||
placeholder="申请名称、发起人"
|
||||
v-model="search"
|
||||
clearable
|
||||
custom-class="border-0"
|
||||
:maxlength="50"
|
||||
prefix-icon="search"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</view>
|
||||
<wd-tabs v-model="currentIndex" class="pt-3" auto-line-width @click="handleChange">
|
||||
<wd-tab :title="item" v-for="(item, index) in tabs" :key="item" :name="index" />
|
||||
</wd-tabs>
|
||||
<swiper :current="currentIndex" @change="changeIndex">
|
||||
<swiper-item v-for="(item, index) in tabs" :key="item" class="flex flex-col">
|
||||
<view @click="closeOutside">
|
||||
<wd-drop-menu>
|
||||
<wd-drop-menu-item
|
||||
v-model="typeList[index]"
|
||||
:options="typeOptionList[index]"
|
||||
@change="typeChange"
|
||||
/>
|
||||
<wd-drop-menu-item
|
||||
v-model="dateList[index]"
|
||||
:options="dateOptions"
|
||||
@change="dateChange"
|
||||
/>
|
||||
</wd-drop-menu>
|
||||
</view>
|
||||
<scroll-view :scroll-y="true" class="flex-1 box-border">
|
||||
<view class="pt-2">
|
||||
<view
|
||||
v-for="item in 10"
|
||||
:key="item"
|
||||
class="mx-4 my-2 p-4 bg-white shadow-sm rounded-2 text-3.5"
|
||||
@click="toDetail(item)"
|
||||
>
|
||||
<view class="flex flex-items-center mb-2">
|
||||
<view class="text-4.5 font-bold">请假</view>
|
||||
<view
|
||||
class="ml-a px-3 py-1 border-solid border-[#2bbbc3] border-1 color-#2bbbc3 rounded"
|
||||
>
|
||||
通过
|
||||
</view>
|
||||
</view>
|
||||
<view class="mb-2">请假类型:年假</view>
|
||||
<view class="mb-2">开始时间:2025-12-31</view>
|
||||
<view class="mb-2">结束时间:2025-12-31</view>
|
||||
<view class="flex flex-items-center">
|
||||
<image class="w-8 h-8" src="/static/images/icon_default_avatar.png"></image>
|
||||
<view class="ml-4">xxx</view>
|
||||
<view class="ml-a">2025-12-25</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="py-6 mx-30%">
|
||||
<wd-divider color="#515357">已经到底了</wd-divider>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useQueue } from 'wot-design-uni'
|
||||
|
||||
const search = ref<string>('')
|
||||
|
||||
const currentIndex = ref<number>(0)
|
||||
|
||||
const tabs = ref<string[]>(['待办', '已办', '抄送我', '已发起'])
|
||||
|
||||
const { closeOutside } = useQueue()
|
||||
|
||||
const typeList = ref<Array<number>>([0, 0, 0, 0])
|
||||
const dateList = ref<Array<number>>([0, 0, 0, 0])
|
||||
|
||||
const typeOptionList = ref<Array<Array<Record<string, number>>>>([
|
||||
[
|
||||
{ label: '全部', value: 0 },
|
||||
{ label: '补卡', value: 1 },
|
||||
{ label: '请假', value: 2 }
|
||||
],
|
||||
[
|
||||
{ label: '全部', value: 0 },
|
||||
{ label: '调休', value: 1 }
|
||||
],
|
||||
[
|
||||
{ label: '全部', value: 0 },
|
||||
{ label: '补卡', value: 1 },
|
||||
{ label: '请假', value: 2 }
|
||||
],
|
||||
[
|
||||
{ label: '全部', value: 0 },
|
||||
{ label: '补卡', value: 1 },
|
||||
{ label: '请假', value: 2 }
|
||||
]
|
||||
])
|
||||
|
||||
const dateOptions = ref<Array<Record<string, number>>>([
|
||||
{ label: '全部日期', value: 0 },
|
||||
{ label: '近7日', value: 1 },
|
||||
{ label: '近14日', value: 2 },
|
||||
{ label: '近30日', value: 3 }
|
||||
])
|
||||
|
||||
const typeChange = ({ value }) => {
|
||||
console.log(value)
|
||||
}
|
||||
|
||||
const dateChange = ({ value }) => {
|
||||
console.log(value)
|
||||
}
|
||||
|
||||
const toDetail = item => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/approval/approval-detail'
|
||||
})
|
||||
}
|
||||
|
||||
const handleChange = value => {
|
||||
currentIndex.value = value.index
|
||||
}
|
||||
|
||||
const changeIndex = e => {
|
||||
currentIndex.value = e.detail.current
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wd-input::after {
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.wd-drop-item {
|
||||
top: calc(var(--window-top) + 48px) !important;
|
||||
}
|
||||
|
||||
:deep(.wd-drop-menu__item.is-active .wd-drop-menu__item-title::after) {
|
||||
opacity: 0 !important;
|
||||
}
|
||||
|
||||
:deep(.wd-drop-menu__list) {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
:deep(.wd-tabs__nav-item) {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
:deep(.wd-tabs__nav-item.is-active) {
|
||||
font-weight: bold;
|
||||
color: #255cf7;
|
||||
}
|
||||
</style>
|
||||
@ -1,273 +0,0 @@
|
||||
<template>
|
||||
<view class="px-2 text-3.5">
|
||||
<view v-if="inline">
|
||||
<view class="flex flex-items-center pos-relative pt-2 pb-1">
|
||||
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
|
||||
<view>{{ title }}</view>
|
||||
<view @click="openDialog" class="flex-1 flex flex-items-center">
|
||||
<view :class="[text ? 'custom-color-black' : 'color-#bfbfbf']" class="ml-a mr-2">
|
||||
{{ text || placeholder }}
|
||||
</view>
|
||||
<wd-icon name="arrow-right" color="rgba(0,0,0,0.25)" size="18px"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="flex flex-items-center pos-relative">
|
||||
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
|
||||
<view>{{ title }}</view>
|
||||
</view>
|
||||
<view class="pt-2" @click="openDialog">
|
||||
<view class="flex flex-items-center flex-justify-between">
|
||||
<view :class="[text ? 'custom-color-black' : 'color-#bfbfbf']">
|
||||
{{ text || placeholder }}
|
||||
</view>
|
||||
<wd-icon name="arrow-right" color="rgba(0,0,0,0.25)" size="18px"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<wd-popup
|
||||
v-model="show"
|
||||
position="bottom"
|
||||
custom-style="border-radius:12rpx;"
|
||||
@after-leave="afterLeave"
|
||||
>
|
||||
<view>
|
||||
<view class="p-4 text-3.5 border-b-1 border-[#dcdcdc] border-solid flex flex-items-center">
|
||||
<view class="font-bold">日期:</view>
|
||||
<view class="font-bold ml-a" v-if="type !== 'dateHalfDay'">{{ date }}</view>
|
||||
</view>
|
||||
<view v-if="(type === 'date' || type === 'datetime') && showPicker">
|
||||
<wd-datetime-picker-view
|
||||
:formatter="formatter"
|
||||
:type="type"
|
||||
v-model="timestamp"
|
||||
label="日期选择"
|
||||
@change="change"
|
||||
/>
|
||||
</view>
|
||||
<view v-if="type === 'dateHalfDay' && showPicker">
|
||||
<wd-tabs v-model="tab">
|
||||
<wd-tab :title="index === 0 ? date : halfDay" v-for="(item, index) in 2" :key="index">
|
||||
<view v-show="index === 0">
|
||||
<wd-datetime-picker-view
|
||||
:formatter="formatter"
|
||||
type="date"
|
||||
v-model="timestamp"
|
||||
@change="change"
|
||||
/>
|
||||
</view>
|
||||
<view v-show="index === 1">
|
||||
<wd-picker-view :columns="['上午', '下午']" v-model="halfDay" @change="change" />
|
||||
</view>
|
||||
</wd-tab>
|
||||
</wd-tabs>
|
||||
</view>
|
||||
<view class="pb-safe">
|
||||
<view class="flex py-3 flex-items-center flex-justify-around text-3.5 px-2 font-bold">
|
||||
<view
|
||||
class="w-45% bg-#eeeff4 custom-color-blue py-2.5 rounded-2 text-center"
|
||||
@click="show = false"
|
||||
>
|
||||
取消
|
||||
</view>
|
||||
<view
|
||||
class="w-45% custom-bg-blue color-white py-2.5 rounded-2 text-center"
|
||||
@click="confirm"
|
||||
>
|
||||
确定
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
const show = ref<boolean>(false)
|
||||
const timestamp = ref<number>(0)
|
||||
const text = ref<string>('')
|
||||
const date = ref<string>('')
|
||||
const halfDay = ref<string>('')
|
||||
const showPicker = ref<boolean>(false)
|
||||
const returnTimestamp = ref<number>(0)
|
||||
|
||||
const tab = ref<number>(0)
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'date'
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
value: {
|
||||
type: [Number, null],
|
||||
default: null
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
disabledText: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
minDate: {
|
||||
type: [Number, null],
|
||||
default: null
|
||||
},
|
||||
maxDate: {
|
||||
type: [Number, null],
|
||||
default: null
|
||||
},
|
||||
minDateText: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
maxDateText: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
inline: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const formatter = (type, value) => {
|
||||
switch (type) {
|
||||
case 'year':
|
||||
return value + '年'
|
||||
case 'month':
|
||||
return value + '月'
|
||||
case 'date':
|
||||
return value + '日'
|
||||
case 'hour':
|
||||
return value + '时'
|
||||
case 'minute':
|
||||
return value + '分'
|
||||
default:
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
const emits = defineEmits(['change'])
|
||||
|
||||
onMounted(() => {
|
||||
if (props.value) {
|
||||
timestamp.value = props.value
|
||||
if (props.type === 'date') {
|
||||
date.value = dayjs(props.value).format('YYYY-M-D')
|
||||
text.value = date.value
|
||||
} else if (props.type === 'datetime') {
|
||||
date.value = dayjs(props.value).format('YYYY-M-D HH:mm')
|
||||
text.value = date.value
|
||||
} else if (props.type === 'dateHalfDay') {
|
||||
date.value = dayjs(props.value).format('YYYY年M月D日')
|
||||
halfDay.value = dayjs(props.value).hour() < 12 ? '上午' : '下午'
|
||||
text.value = `${date.value} ${halfDay.value}`
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const change = ({ value }) => {
|
||||
if (props.type === 'date') {
|
||||
date.value = dayjs(value).format('YYYY-M-D')
|
||||
} else if (props.type === 'datetime') {
|
||||
date.value = dayjs(value).format('YYYY-M-D HH:mm')
|
||||
} else if (props.type === 'dateHalfDay') {
|
||||
if (tab.value === 0) {
|
||||
date.value = dayjs(value).format('YYYY年M月D日')
|
||||
} else {
|
||||
halfDay.value = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const openDialog = () => {
|
||||
if (props.disabled) {
|
||||
uni.showToast({
|
||||
title: props.disabledText,
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!props.value) {
|
||||
if (text.value === '') {
|
||||
timestamp.value = new Date().getTime()
|
||||
} else {
|
||||
timestamp.value = returnTimestamp.value
|
||||
}
|
||||
|
||||
if (props.type === 'date') {
|
||||
date.value = dayjs(timestamp.value).format('YYYY-M-D')
|
||||
} else if (props.type === 'datetime') {
|
||||
date.value = dayjs(timestamp.value).format('YYYY-M-D HH:mm')
|
||||
} else if (props.type === 'dateHalfDay') {
|
||||
date.value = dayjs(timestamp.value).format('YYYY年M月D日')
|
||||
halfDay.value = dayjs(timestamp.value).hour() < 12 ? '上午' : '下午'
|
||||
}
|
||||
}
|
||||
showPicker.value = true
|
||||
show.value = true
|
||||
}
|
||||
|
||||
const confirm = () => {
|
||||
if (props.minDate && timestamp.value < props.minDate) {
|
||||
uni.showToast({
|
||||
title: props.minDateText,
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (props.maxDate && timestamp.value > props.maxDate) {
|
||||
uni.showToast({
|
||||
title: props.maxDateText,
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
show.value = false
|
||||
returnTimestamp.value = timestamp.value
|
||||
if (props.type === 'dateHalfDay') {
|
||||
text.value = `${date.value} ${halfDay.value}`
|
||||
} else {
|
||||
text.value = date.value
|
||||
}
|
||||
emits('change', { id: props.id, value: returnTimestamp.value, text: text.value })
|
||||
}
|
||||
|
||||
const afterLeave = () => {
|
||||
showPicker.value = false
|
||||
}
|
||||
|
||||
const clear = () => {
|
||||
text.value = ''
|
||||
date.value = ''
|
||||
halfDay.value = ''
|
||||
returnTimestamp.value = 0
|
||||
emits('change', { id: props.id, value: returnTimestamp.value, text: text.value })
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
clear
|
||||
})
|
||||
</script>
|
||||
@ -1,110 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<DatetimePicker
|
||||
:id="1"
|
||||
ref="startDatetimePicker"
|
||||
title="开始时间"
|
||||
@change="changeDate"
|
||||
:max-date="endTimestamp"
|
||||
max-date-text="开始时间不能晚于结束时间"
|
||||
required
|
||||
:disabled="disabled"
|
||||
:disabled-text="disabledText"
|
||||
:type="unit"
|
||||
></DatetimePicker>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<DatetimePicker
|
||||
:id="2"
|
||||
title="结束时间"
|
||||
ref="endDatetimePicker"
|
||||
:min-date="startTimestamp"
|
||||
min-date-text="结束时间不能早于开始时间"
|
||||
@change="changeDate"
|
||||
required
|
||||
:type="unit"
|
||||
:disabled="disabled"
|
||||
:disabled-text="disabledText"
|
||||
></DatetimePicker>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<Input
|
||||
:id="3"
|
||||
ref="inputComponent"
|
||||
type="number"
|
||||
:title="`${textMap[type]}时长${unit === 'datetime' ? '(小时)' : '(天)'}`"
|
||||
required
|
||||
:readonly="updateTime"
|
||||
placeholder="自动计算"
|
||||
@change="inputChange"
|
||||
></Input>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DatetimePicker from '@/pages/approval/components/DatetimePicker.vue'
|
||||
import Input from '@/pages/approval/components/Input.vue'
|
||||
|
||||
const textMap = {
|
||||
leave: '请假',
|
||||
businessTrip: '出差',
|
||||
goOut: '外出',
|
||||
overtime: '加班'
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
unit: {
|
||||
type: String,
|
||||
default: 'date'
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
disabledText: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
updateTime: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const startTimestamp = ref(0)
|
||||
const endTimestamp = ref(0)
|
||||
|
||||
const startDatetimePicker = ref(null)
|
||||
const endDatetimePicker = ref(null)
|
||||
const inputComponent = ref(null)
|
||||
|
||||
const changeDate = e => {
|
||||
if (e.id === 1) {
|
||||
startTimestamp.value = e.value
|
||||
} else {
|
||||
endTimestamp.value = e.value
|
||||
}
|
||||
}
|
||||
|
||||
const inputChange = e => {
|
||||
console.log('inputChange', e)
|
||||
}
|
||||
|
||||
const clear = () => {
|
||||
startDatetimePicker.value.clear()
|
||||
endDatetimePicker.value.clear()
|
||||
inputComponent.value.clear()
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
clear
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -1,18 +0,0 @@
|
||||
<template>
|
||||
<view class="px-2 text-3 pb-2">
|
||||
<view class="break-all">{{ title }}</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@ -1,145 +0,0 @@
|
||||
<template>
|
||||
<view class="pb-3 mb-2">
|
||||
<Visitor></Visitor>
|
||||
<view class="bg-white mx-4 px-2 pt-3 pb-4 rounded-2 shadow-sm">
|
||||
<Input
|
||||
:id="0"
|
||||
value="单行"
|
||||
title="单行文本"
|
||||
:required="true"
|
||||
placeholder="单行文本"
|
||||
@change="inputChange"
|
||||
></Input>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<Textarea
|
||||
:id="1"
|
||||
title="多行文本"
|
||||
:required="false"
|
||||
placeholder="多行文本"
|
||||
@change="textareaChange"
|
||||
></Textarea>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<SelectPicker
|
||||
:value="1"
|
||||
:id="2"
|
||||
title="单选框"
|
||||
placeholder="单选"
|
||||
:columns="columns"
|
||||
></SelectPicker>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<SelectPicker
|
||||
:value="[0]"
|
||||
:id="3"
|
||||
title="多选框"
|
||||
placeholder="多选"
|
||||
type="checkbox"
|
||||
:columns="columns"
|
||||
></SelectPicker>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<Input
|
||||
:id="4"
|
||||
type="number"
|
||||
title="数字"
|
||||
:required="true"
|
||||
placeholder="数字"
|
||||
@change="inputChange"
|
||||
></Input>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<DatetimePicker :id="5" title="日期1" @change="changeDate"></DatetimePicker>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<DatetimePicker
|
||||
:id="6"
|
||||
title="日期2"
|
||||
type="dateHalfDay"
|
||||
@change="changeDate"
|
||||
></DatetimePicker>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<DatetimePicker
|
||||
:id="7"
|
||||
type="datetime"
|
||||
:value="1737043380000"
|
||||
title="日期3"
|
||||
@change="changeDate"
|
||||
></DatetimePicker>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<Images :id="8" title="图片"></Images>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<Description
|
||||
:id="9"
|
||||
title="图片21378912378923718982371217389712397837889713247893428793142897134728900978"
|
||||
></Description>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<NavigatorSelector :id="10" title="成员" type="member" :multiple="true"></NavigatorSelector>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<NavigatorSelector
|
||||
:id="11"
|
||||
title="部门"
|
||||
type="department"
|
||||
:multiple="true"
|
||||
></NavigatorSelector>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<Leave :id="12"></Leave>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<DatetimePickerGroup :id="13" type="businessTrip" unit="date"></DatetimePickerGroup>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<DatetimePickerGroup :id="14" type="goOut" unit="dateHalfDay"></DatetimePickerGroup>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<Overtime :id="15"></Overtime>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<DatetimePicker
|
||||
:id="16"
|
||||
type="datetime"
|
||||
required
|
||||
title="补卡时间"
|
||||
@change="changeDate"
|
||||
></DatetimePicker>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Input from '@/pages/approval/components/Input.vue'
|
||||
import Textarea from '@/pages/approval/components/Textarea.vue'
|
||||
import SelectPicker from '@/pages/approval/components/SelectPicker.vue'
|
||||
import DatetimePicker from '@/pages/approval/components/DatetimePicker.vue'
|
||||
import Images from '@/pages/approval/components/Images.vue'
|
||||
import Description from '@/pages/approval/components/Description.vue'
|
||||
import NavigatorSelector from '@/pages/approval/components/NavigatorSelector.vue'
|
||||
import Leave from '@/pages/approval/components/Leave.vue'
|
||||
import DatetimePickerGroup from '@/pages/approval/components/DatetimePickerGroup.vue'
|
||||
import Overtime from '@/pages/approval/components/Overtime.vue'
|
||||
import Visitor from '@/pages/approval/components/Visitor.vue'
|
||||
|
||||
const columns = ref<Record<number, string>>([
|
||||
{
|
||||
value: 0,
|
||||
label: '男装'
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
label: '奢侈品'
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '女装'
|
||||
}
|
||||
])
|
||||
|
||||
const inputChange = e => {
|
||||
console.log('inputChange', e)
|
||||
}
|
||||
|
||||
const textareaChange = e => {
|
||||
console.log('textareaChange', e)
|
||||
}
|
||||
|
||||
const changeDate = e => {
|
||||
console.log('changeDate', e)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wd-divider {
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
</style>
|
||||
@ -1,65 +0,0 @@
|
||||
<template>
|
||||
<view class="px-2 text-3.5">
|
||||
<view class="flex flex-items-center pos-relative">
|
||||
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
|
||||
<view>{{ title }}</view>
|
||||
</view>
|
||||
<view class="pt-3">
|
||||
<wd-upload
|
||||
:file-list="fileList"
|
||||
multiple
|
||||
:limit="9"
|
||||
image-mode="aspectFill"
|
||||
:size-type="['original']"
|
||||
action="https://mockapi.eolink.com/zhTuw2P8c29bc981a741931bdd86eb04dc1e8fd64865cb5/upload"
|
||||
@change="handleChange"
|
||||
></wd-upload>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const fileList = ref<any[]>([])
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if (props.value.length > 0) {
|
||||
fileList.value = props.value
|
||||
}
|
||||
})
|
||||
|
||||
const handleChange = ({ fileList: files }) => {
|
||||
console.log('handleChange', files)
|
||||
fileList.value = files
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.wd-upload__evoke),
|
||||
:deep(.wd-upload__status-content),
|
||||
:deep(.wd-upload__picture) {
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
:deep(.wd-upload__evoke) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
@ -1,110 +0,0 @@
|
||||
<template>
|
||||
<view class="px-2 text-3.5">
|
||||
<view v-if="inline">
|
||||
<view class="flex flex-items-center pos-relative">
|
||||
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
|
||||
<view>{{ title }}</view>
|
||||
<wd-input
|
||||
class="flex-1 ml-2"
|
||||
:type="type"
|
||||
custom-class="!bg-transparent"
|
||||
:custom-input-class="inline ? 'text-right' : 'text-left'"
|
||||
:placeholder="placeholder"
|
||||
:maxlength="maxlength ?? (type === 'text' ? 30 : 15)"
|
||||
v-model="text"
|
||||
:readonly="readonly"
|
||||
@input="change(id, $event)"
|
||||
></wd-input>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="flex flex-items-center pos-relative">
|
||||
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
|
||||
<view>{{ title }}</view>
|
||||
</view>
|
||||
<view class="pt-2">
|
||||
<wd-input
|
||||
:type="type"
|
||||
custom-class="!bg-transparent"
|
||||
:placeholder="placeholder"
|
||||
:maxlength="maxlength ?? (type === 'text' ? 30 : 15)"
|
||||
v-model="text"
|
||||
:readonly="readonly"
|
||||
@input="change(id, $event)"
|
||||
></wd-input>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const emits = defineEmits(['change'])
|
||||
|
||||
const text = ref<string>('')
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'text'
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请输入'
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
inline: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
maxlength: {
|
||||
type: [Number, null],
|
||||
default: null
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
text.value = props.value
|
||||
})
|
||||
|
||||
const change = (id, data) => {
|
||||
emits('change', { id, value: data.value })
|
||||
}
|
||||
|
||||
const clear = () => {
|
||||
text.value = ''
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
clear
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wd-input::after {
|
||||
height: 0 !important;
|
||||
}
|
||||
|
||||
:deep(.wd-input__inner) {
|
||||
height: var(--wot-input-inner-height, 24px);
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
</style>
|
||||
@ -1,94 +0,0 @@
|
||||
<template>
|
||||
<view class="px-2 text-3.5">
|
||||
<view v-if="inline">
|
||||
<view class="flex flex-items-center pos-relative py-1.5">
|
||||
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
|
||||
<view>{{ title }}</view>
|
||||
<view
|
||||
class="flex-1 ml-a text-right"
|
||||
@click="toSelect"
|
||||
:class="[text ? 'custom-color-black' : 'color-#bfbfbf']"
|
||||
>
|
||||
{{ text || placeholder }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="flex flex-items-center pos-relative">
|
||||
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
|
||||
<view>{{ title }}</view>
|
||||
</view>
|
||||
<view class="py-2" @click="toSelect">
|
||||
<view class="flex flex-items-center flex-justify-between">
|
||||
<view :class="[text ? 'custom-color-black' : 'color-#bfbfbf']">
|
||||
{{ text || placeholder }}
|
||||
</view>
|
||||
<wd-icon name="arrow-right" color="rgba(0,0,0,0.25)" size="18px"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<wd-keyboard
|
||||
:mode="type"
|
||||
title="键盘"
|
||||
:hide-on-click-outside="true"
|
||||
v-model:visible="visible"
|
||||
@input="onInput"
|
||||
closeText="确认"
|
||||
@delete="onDelete"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const text = ref<string>('')
|
||||
const visible = ref<boolean>(false)
|
||||
|
||||
const onInput = value => {
|
||||
if (props.maxlength && text.value.length >= props.maxlength) return
|
||||
text.value += value
|
||||
}
|
||||
const onDelete = () => {
|
||||
text.value = text.value.slice(0, -1)
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
value: {
|
||||
type: [Number, null],
|
||||
default: null
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请输入'
|
||||
},
|
||||
maxlength: {
|
||||
type: [Number, null],
|
||||
default: null
|
||||
},
|
||||
inline: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const toSelect = () => {
|
||||
visible.value = true
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -1,97 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<SelectPicker
|
||||
:id="0"
|
||||
title="请假类型"
|
||||
placeholder="请选择"
|
||||
:columns="columns"
|
||||
required
|
||||
@change="changeSelect"
|
||||
></SelectPicker>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<DatetimePickerGroup
|
||||
ref="timeGroup"
|
||||
type="leave"
|
||||
:disabled="!leaveType"
|
||||
:updateTime="updateTime"
|
||||
:unit="leaveType?.unit ?? 'date'"
|
||||
disabled-text="请选择请假类型"
|
||||
:id="1"
|
||||
></DatetimePickerGroup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import SelectPicker from '@/pages/approval/components/SelectPicker.vue'
|
||||
import DatetimePickerGroup from '@/pages/approval/components/DatetimePickerGroup.vue'
|
||||
|
||||
const leaveType = ref(null)
|
||||
const timeGroup = ref(null)
|
||||
|
||||
const columns = ref<Record<number, string>>([
|
||||
{
|
||||
value: 0,
|
||||
label: '年假',
|
||||
unit: 'date'
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
label: '事假',
|
||||
unit: 'dateHalfDay'
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '病假',
|
||||
unit: 'datetime'
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: '婚假',
|
||||
unit: 'date',
|
||||
limit: 5
|
||||
},
|
||||
{
|
||||
value: 4,
|
||||
label: '产假',
|
||||
unit: 'datetime',
|
||||
limit: 24.5
|
||||
},
|
||||
{
|
||||
value: 5,
|
||||
label: '陪产假',
|
||||
unit: 'datetime'
|
||||
},
|
||||
{
|
||||
value: 6,
|
||||
label: '丧假',
|
||||
unit: 'date'
|
||||
},
|
||||
{
|
||||
value: 7,
|
||||
label: '哺乳假',
|
||||
unit: 'date'
|
||||
}
|
||||
])
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
updateTime: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const changeSelect = e => {
|
||||
leaveType.value = e.value
|
||||
timeGroup.value.clear()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wd-divider {
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
</style>
|
||||
@ -1,94 +0,0 @@
|
||||
<template>
|
||||
<view class="px-2 text-3.5">
|
||||
<view v-if="inline">
|
||||
<view class="flex flex-items-center pos-relative pb-1.5" @click="toSelect">
|
||||
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
|
||||
<view>{{ title }}</view>
|
||||
<view class="ml-a mr-2" :class="[text ? 'custom-color-black' : 'color-#bfbfbf']">
|
||||
{{ text || placeholder }}
|
||||
</view>
|
||||
<wd-icon name="arrow-right" color="rgba(0,0,0,0.25)" size="18px"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="flex flex-items-center pos-relative">
|
||||
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
|
||||
<view>{{ title }}</view>
|
||||
</view>
|
||||
<view class="pt-2" @click="toSelect">
|
||||
<view class="flex flex-items-center flex-justify-between">
|
||||
<view :class="[text ? 'custom-color-black' : 'color-#bfbfbf']">
|
||||
{{ text || placeholder }}
|
||||
</view>
|
||||
<wd-icon name="arrow-right" color="rgba(0,0,0,0.25)" size="18px"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const text = ref<string | null>(null)
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
value: {
|
||||
type: [Number, null],
|
||||
default: null
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
},
|
||||
inline: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const toSelect = () => {
|
||||
if (props.type === 'accessControl') {
|
||||
uni.navigateTo({
|
||||
url: `/pages/select/select-access-control`,
|
||||
events: {
|
||||
change: res => {
|
||||
console.log(1111, res)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const params = {
|
||||
type: props.type,
|
||||
multiple: props.multiple,
|
||||
title: props.type === 'member' ? '选择审批用户' : '选择部门'
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: `/pages/select/select-organization?params=${JSON.stringify(params)}`,
|
||||
events: {
|
||||
change: res => {
|
||||
console.log(1111, res)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -1,43 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<DatetimePicker
|
||||
:id="0"
|
||||
ref="startDatetimePicker"
|
||||
title="加班日期"
|
||||
@change="changeDate"
|
||||
required
|
||||
></DatetimePicker>
|
||||
<wd-divider v-if="timestamp" color="#bcbfbe"></wd-divider>
|
||||
<DatetimePickerGroup
|
||||
v-if="timestamp"
|
||||
type="overtime"
|
||||
unit="datetime"
|
||||
:id="1"
|
||||
></DatetimePickerGroup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DatetimePickerGroup from '@/pages/approval/components/DatetimePickerGroup.vue'
|
||||
import DatetimePicker from '@/pages/approval/components/DatetimePicker.vue'
|
||||
|
||||
const timestamp = ref<number>(0)
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const changeDate = e => {
|
||||
timestamp.value = e.value
|
||||
console.log('changeDate', e)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.wd-divider {
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
</style>
|
||||
@ -1,128 +0,0 @@
|
||||
<template>
|
||||
<view class="px-2 text-3.5">
|
||||
<view v-if="inline">
|
||||
<view class="flex flex-items-center pos-relative">
|
||||
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
|
||||
<view>{{ title }}</view>
|
||||
<wd-select-picker
|
||||
class="flex-1"
|
||||
align-right
|
||||
:type="type"
|
||||
:title="placeholder"
|
||||
:show-confirm="type === 'checkbox'"
|
||||
v-model="picker"
|
||||
:columns="columns"
|
||||
size="large"
|
||||
@change="change"
|
||||
select-size="large"
|
||||
></wd-select-picker>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="flex flex-items-center pos-relative">
|
||||
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
|
||||
<view>{{ title }}</view>
|
||||
</view>
|
||||
<view class="pt-2">
|
||||
<wd-select-picker
|
||||
:type="type"
|
||||
:title="placeholder"
|
||||
:show-confirm="type === 'checkbox'"
|
||||
v-model="picker"
|
||||
:columns="columns"
|
||||
size="large"
|
||||
@change="change"
|
||||
select-size="large"
|
||||
></wd-select-picker>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const picker = ref(-1)
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'radio'
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请输入'
|
||||
},
|
||||
value: {
|
||||
type: [Number, Array, null],
|
||||
default: null
|
||||
},
|
||||
columns: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
inline: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const emits = defineEmits(['change'])
|
||||
|
||||
onMounted(() => {
|
||||
if (props.value) {
|
||||
picker.value = props.value
|
||||
}
|
||||
})
|
||||
|
||||
const change = ({ value }) => {
|
||||
emits('change', { id: props.id, value: props.columns.find(item => item.value === value) })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.wd-select-picker__cell) {
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
:deep(.wd-radio-group),
|
||||
:deep(.wd-checkbox-group) {
|
||||
background-color: #ffffff;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
:deep(.wd-action-sheet) {
|
||||
background-color: #f3f5fa;
|
||||
}
|
||||
|
||||
:deep(.uni-scroll-view-content) {
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
:deep(.wd-radio),
|
||||
:deep(.wd-checkbox) {
|
||||
position: relative;
|
||||
padding: 1rem !important;
|
||||
}
|
||||
|
||||
:deep(.wd-radio)::after,
|
||||
:deep(.wd-checkbox)::after {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 4%;
|
||||
width: 92%;
|
||||
content: '';
|
||||
border-bottom: 1px solid #efefef;
|
||||
}
|
||||
</style>
|
||||
@ -1,71 +0,0 @@
|
||||
<template>
|
||||
<view class="px-2 text-3.5">
|
||||
<view class="flex flex-items-center pos-relative">
|
||||
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
|
||||
<view>{{ title }}</view>
|
||||
</view>
|
||||
<view class="pt-2">
|
||||
<wd-textarea
|
||||
custom-class="!bg-transparent"
|
||||
custom-textarea-class="h-16"
|
||||
:placeholder="placeholder"
|
||||
:maxlength="250"
|
||||
v-model="text"
|
||||
show-word-limit
|
||||
@input="change(id, $event)"
|
||||
></wd-textarea>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const emits = defineEmits(['change'])
|
||||
|
||||
const text = ref<string>('')
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请输入'
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
text.value = props.value
|
||||
})
|
||||
|
||||
const change = (id, data) => {
|
||||
emits('change', { id, value: data.value })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.wd-textarea__value),
|
||||
:deep(.wd-textarea__count) {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
:deep(.wd-textarea__inner) {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.wd-textarea {
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
@ -1,194 +0,0 @@
|
||||
<template>
|
||||
<view class="px-2 text-3.5">
|
||||
<view v-if="inline">
|
||||
<view class="flex flex-items-center pos-relative" @click="toSelect">
|
||||
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
|
||||
<view>{{ title }}</view>
|
||||
<view class="ml-a mr-2" :class="[text ? 'custom-color-black' : 'color-#bfbfbf']">
|
||||
{{ text || placeholder }}
|
||||
</view>
|
||||
<wd-icon name="arrow-right" color="rgba(0,0,0,0.25)" size="18px"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="flex flex-items-center pos-relative">
|
||||
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
|
||||
<view>{{ title }}</view>
|
||||
</view>
|
||||
<view class="py-2" @click="toSelect">
|
||||
<view class="flex flex-items-center flex-justify-between">
|
||||
<view :class="[text ? 'custom-color-black' : 'color-#bfbfbf']">
|
||||
{{ text || placeholder }}
|
||||
</view>
|
||||
<wd-icon name="arrow-right" color="rgba(0,0,0,0.25)" size="18px"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<wd-popup v-model="show" position="bottom" custom-style="border-radius:12rpx;">
|
||||
<view v-if="showDuration">
|
||||
<view
|
||||
class="px-4 py-2 text-3.5 border-b-1 border-[#dcdcdc] border-solid flex flex-items-center"
|
||||
>
|
||||
<view @click="show = false">取消</view>
|
||||
<view class="font-bold text-4 flex-1 text-center">访问时长</view>
|
||||
<view class="flex flex-items-center" @click="changeSelect">
|
||||
<view class="custom-color-blue">自定义时间</view>
|
||||
<wd-icon name="arrow-right" size="14px" class="ml-1" color="#255cf7"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view class="h-60 text-3.5" :scroll-y="true">
|
||||
<view
|
||||
v-for="item in durationList"
|
||||
:key="item.value"
|
||||
@click="changeDuration(item)"
|
||||
class="py-4 px-4 flex flex-items-center"
|
||||
>
|
||||
<view>{{ item.label }}</view>
|
||||
<view
|
||||
class="bg-#f3f5fa ml-a w-12 h-6 rounded-5 flex flex-items-center flex-justify-center"
|
||||
>
|
||||
<wd-icon
|
||||
v-if="duration === item.label"
|
||||
name="check"
|
||||
size="15px"
|
||||
class="ml-1"
|
||||
color="#255cf7"
|
||||
></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view
|
||||
class="px-4 py-2 text-3.5 border-b-1 border-[#dcdcdc] border-solid flex flex-items-center"
|
||||
>
|
||||
<view class="flex flex-items-center" @click="showDuration = true">
|
||||
<wd-icon name="arrow-left" size="14px" class="ml-1" color="#0d0f10"></wd-icon>
|
||||
<view class="custom-color-black">返回</view>
|
||||
</view>
|
||||
<view class="font-bold text-4 flex-1 text-center">时间选择器</view>
|
||||
<wd-icon
|
||||
name="close"
|
||||
size="14px"
|
||||
class="ml-1"
|
||||
color="#0d0f10"
|
||||
@click="show = false"
|
||||
></wd-icon>
|
||||
</view>
|
||||
<wd-datetime-picker-view
|
||||
:formatter="formatter"
|
||||
type="datetime"
|
||||
v-model="timestamp"
|
||||
@change="change"
|
||||
/>
|
||||
</view>
|
||||
<view
|
||||
@click="confirm"
|
||||
class="py-2.5 rounded custom-bg-blue w-90% mx-5% font-bold text-center color-white text-3.5 my-2"
|
||||
>
|
||||
完成
|
||||
</view>
|
||||
</wd-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
const text = ref<string | null>(null)
|
||||
const show = ref<boolean>(false)
|
||||
const timestamp = ref<number>(0)
|
||||
const duration = ref<string>('')
|
||||
|
||||
const showDuration = ref<boolean>(true)
|
||||
|
||||
const formatter = (type, value) => {
|
||||
switch (type) {
|
||||
case 'year':
|
||||
return value + '年'
|
||||
case 'month':
|
||||
return value + '月'
|
||||
case 'date':
|
||||
return value + '日'
|
||||
case 'hour':
|
||||
return value + '时'
|
||||
case 'minute':
|
||||
return value + '分'
|
||||
default:
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
value: {
|
||||
type: [String, null],
|
||||
default: null
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
},
|
||||
inline: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const durationList = [
|
||||
{ label: '30分钟', value: 1800000 },
|
||||
{ label: '1小时', value: 3600000 },
|
||||
{ label: '2小时', value: 7200000 },
|
||||
{ label: '3小时', value: 10800000 },
|
||||
{ label: '5小时', value: 18000000 },
|
||||
{ label: '8小时', value: 28800000 },
|
||||
{ label: '12小时', value: 43200000 },
|
||||
{ label: '24小时', value: 86400000 }
|
||||
]
|
||||
|
||||
onMounted(() => {
|
||||
if (props.value) {
|
||||
text.value = props.value
|
||||
duration.value = props.value
|
||||
}
|
||||
})
|
||||
|
||||
const changeSelect = () => {
|
||||
timestamp.value = new Date().getTime()
|
||||
showDuration.value = false
|
||||
}
|
||||
|
||||
const toSelect = () => {
|
||||
show.value = true
|
||||
}
|
||||
|
||||
const change = value => {
|
||||
timestamp.value = value.value
|
||||
duration.value = ''
|
||||
}
|
||||
|
||||
const changeDuration = item => {
|
||||
duration.value = item.label
|
||||
timestamp.value = 0
|
||||
}
|
||||
|
||||
const confirm = () => {
|
||||
if (timestamp.value === 0) {
|
||||
text.value = duration.value
|
||||
} else {
|
||||
text.value = dayjs(timestamp.value).format('YYYY-M-D HH:mm')
|
||||
}
|
||||
show.value = false
|
||||
}
|
||||
</script>
|
||||
@ -1,89 +0,0 @@
|
||||
<template>
|
||||
<view class="bg-white mx-4 px-2 pb-3 pt-4.5 rounded-2 mb-2 shadow-sm">
|
||||
<Input :id="0" title="访客姓名" :required="true" @change="inputChange" inline></Input>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<Input
|
||||
:id="1"
|
||||
title="访客手机"
|
||||
:required="true"
|
||||
:maxlength="11"
|
||||
@change="inputChange"
|
||||
inline
|
||||
type="number"
|
||||
></Input>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<SelectPicker required :id="2" title="访客类型" :columns="columns" inline></SelectPicker>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<NavigatorSelector :id="3" title="通行门禁点" type="accessControl" inline></NavigatorSelector>
|
||||
</view>
|
||||
<view class="bg-white mx-4 px-2 py-3 rounded-2 mb-2 shadow-sm">
|
||||
<Keyboard :id="4" title="车牌号码" type="car" :maxlength="8" inline></Keyboard>
|
||||
</view>
|
||||
<view class="bg-white mx-4 px-2 pt-3 pb-2 rounded-2 mb-2 shadow-sm">
|
||||
<DatetimePicker
|
||||
:id="5"
|
||||
ref="startDatetimePicker"
|
||||
title="预约到访时间"
|
||||
@change="changeDate"
|
||||
type="datetime"
|
||||
inline
|
||||
required
|
||||
></DatetimePicker>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<VisitDuration :id="6" title="访问时长" required value="2小时" inline></VisitDuration>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<Input :id="7" title="同行人数" @change="inputChange" inline></Input>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<Input :id="8" title="访问单位" @change="inputChange" inline></Input>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<Input :id="9" title="到访事由说明" @change="inputChange" inline></Input>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<Input :id="10" title="访问地址" @change="inputChange" inline></Input>
|
||||
<wd-divider color="#bcbfbe"></wd-divider>
|
||||
<Description :id="11" title="表单通过后,访客将收到断音邀请通知"></Description>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Input from '@/pages/approval/components/Input.vue'
|
||||
import SelectPicker from '@/pages/approval/components/SelectPicker.vue'
|
||||
import Description from '@/pages/approval/components/Description.vue'
|
||||
import Keyboard from '@/pages/approval/components/Keyboard.vue'
|
||||
import DatetimePicker from '@/pages/approval/components/DatetimePicker.vue'
|
||||
import NavigatorSelector from '@/pages/approval/components/NavigatorSelector.vue'
|
||||
import VisitDuration from '@/pages/approval/components/VisitDuration.vue'
|
||||
|
||||
const columns = ref<Record<number, string>>([
|
||||
{
|
||||
value: 0,
|
||||
label: '外卖快递'
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
label: '会议洽谈'
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '探亲访友'
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: '业务沟通'
|
||||
}
|
||||
])
|
||||
|
||||
const inputChange = e => {
|
||||
console.log('inputChange', e)
|
||||
}
|
||||
|
||||
const changeDate = e => {
|
||||
// timestamp.value = e.value
|
||||
console.log('changeDate', e)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wd-divider {
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
</style>
|
||||
@ -1,42 +0,0 @@
|
||||
<route lang="json5">
|
||||
{
|
||||
style: {
|
||||
navigationStyle: 'custom',
|
||||
disableScroll: true
|
||||
}
|
||||
}
|
||||
</route>
|
||||
<template>
|
||||
<view class="h-100vh flex flex-col">
|
||||
<TopNavigation :title="title"></TopNavigation>
|
||||
<scroll-view class="flex-1 box-border" :scroll-y="true">
|
||||
<Form></Form>
|
||||
<ApprovalCreate></ApprovalCreate>
|
||||
</scroll-view>
|
||||
<view class="pb-safe border-#eef0f5 border-t-solid">
|
||||
<view class="flex flex-items-center flex-justify-around py-3 px-3">
|
||||
<view class="py-2 w-45% text-center bg-#e2e5ea custom-color-blue rounded-2">保存草稿</view>
|
||||
<view class="opacity-60% py-2 w-45% text-center custom-bg-blue color-white rounded-2">
|
||||
提交
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Form from '@/pages/approval/components/Form.vue'
|
||||
import ApprovalCreate from '@/pages/approval/components/ApprovalCreate.vue'
|
||||
|
||||
const title = ref<string>('')
|
||||
const id = ref<number>(null)
|
||||
|
||||
onLoad(options => {
|
||||
if (options.title) {
|
||||
title.value = options.title
|
||||
}
|
||||
if (options.id) {
|
||||
id.value = Number(options.id)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@ -1,91 +0,0 @@
|
||||
<route lang="json5" type="page">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<view v-if="canClockIn">
|
||||
<view class="bg-white rounded-2 p-4 box-border mx-3">
|
||||
<view v-for="(item, index) in clockInList" :key="index">
|
||||
<view class="flex flex-row flex-justify-between items-center">
|
||||
<view class="font-bold text-4">{{ item.title }}</view>
|
||||
<view class="color-[#3372FA]">{{ item.status }}</view>
|
||||
</view>
|
||||
<view
|
||||
:class="item.title == '上班' ? '' : 'inline-block'"
|
||||
class="hpx bg-gray-100 my-3"
|
||||
></view>
|
||||
<view v-if="item.isClockIn == false">
|
||||
<view @click="goRules()" class="color-[#3372FA]">考勤 ></view>
|
||||
<view
|
||||
class="gradual w-30 h-30 mx-a rounded-36 mt-15 shadow shadow-blue-400 shadow-lg flex flex-col items-center justify-center color-white"
|
||||
>
|
||||
<view class="text-6.5 font-bold">
|
||||
{{ time.getHours().toString().padStart(2, '0') }}:{{
|
||||
time.getMinutes().toString().padStart(2, '0')
|
||||
}}
|
||||
</view>
|
||||
<view class="text-3 font-300">点击打卡</view>
|
||||
</view>
|
||||
<view class="flex flex-row flex-justify-center items-center my-5">
|
||||
<view class="i-carbon-location-filled color-[#3372FA]"></view>
|
||||
<view class="ml-1 text-3">你已在打卡范围内</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="bg-white rounded-2 pt-20 pb-15 box-border mx-3 pt-2">
|
||||
<view class="text-center">
|
||||
<image src="/static/images/icon_wechat.png" class="w-30 h30" />
|
||||
</view>
|
||||
<view class="text-center mt-2 color-gray">你所在考勤组无法手机打卡</view>
|
||||
<view class="text-center color-gray">请在考勤机或者门禁设备上打卡</view>
|
||||
</view>
|
||||
<view class="w-100% h-17 bg-[#3372FA] mt-2 rounded-2" @click="goHelper"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
const canClockIn = ref(true)
|
||||
const time = ref(new Date())
|
||||
onMounted(() => {
|
||||
setInterval(() => {
|
||||
time.value = new Date()
|
||||
}, 1000)
|
||||
})
|
||||
const clockInList = ref([
|
||||
{
|
||||
title: '上班',
|
||||
status: '正常',
|
||||
isClockIn: true
|
||||
},
|
||||
{
|
||||
title: '下班',
|
||||
status: '未打卡',
|
||||
isClockIn: false
|
||||
}
|
||||
])
|
||||
const goRules = () => {
|
||||
console.log('goRules')
|
||||
uni.navigateTo({
|
||||
url: '/pages/attendance/attendance-rules'
|
||||
})
|
||||
// todo goRules
|
||||
}
|
||||
const goHelper = () => {
|
||||
// todo goHelper
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.gradual {
|
||||
background: linear-gradient(to bottom, #50a0f5, #1e6eed);
|
||||
}
|
||||
</style>
|
||||
@ -1,111 +0,0 @@
|
||||
<route lang="json5" type="page">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<view class="mx-4 pt-2">
|
||||
<view
|
||||
class="my-2 p-3.5 flex flex-justify-between rounded-2.2 items-center bg-white"
|
||||
@click="goAddGroup"
|
||||
>
|
||||
<view class="color-[#3372FA]">添加考勤组</view>
|
||||
<wd-icon name="add-circle" class="color-[#3372FA]" size="20"></wd-icon>
|
||||
</view>
|
||||
<view class="my-2 p-3.5 flex flex-justify-between rounded-2.2 items-center bg-white">
|
||||
<view class="flex flex-col">
|
||||
<view>考勤</view>
|
||||
<view class="text-gray mt-1 text-3">固定班制</view>
|
||||
</view>
|
||||
<wd-icon name="arrow-right" class="text-gray" size="20"></wd-icon>
|
||||
</view>
|
||||
<view class="text-gray mt-4 ml-3 text-3 mb-2">其他设置</view>
|
||||
<view class="flex flex-row flex-justify-between">
|
||||
<view
|
||||
@click="goClasses()"
|
||||
class="p-3.5 bg-white rounded-2.2 flex-1 mr-1 flex flex-row items-center"
|
||||
>
|
||||
<image src="/static/images/icon_wechat.png" class="w-6 h-6 mr-2" />
|
||||
<view class="text-3">班次管理</view>
|
||||
</view>
|
||||
<view
|
||||
@click="goIssueRecord"
|
||||
class="p-3.5 bg-white rounded-2.2 flex-1 ml-1 flex flex-row items-center"
|
||||
>
|
||||
<image src="/static/images/icon_wechat.png" class="w-6 h-6 mr-2" />
|
||||
<view class="text-3">下发记录</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="text-gray mt-4 ml-3 text-3 mb-2">了解详情</view>
|
||||
<view class="flex flex-wrap bg-white rounded-2.2 px-3 py-1.5 flex-justify-between">
|
||||
<view
|
||||
v-for="(item, index) in [
|
||||
'电脑网页端',
|
||||
'微信小程序',
|
||||
'人脸-指纹-卡片',
|
||||
'假勤-补卡申请',
|
||||
'打卡问题检测',
|
||||
'打卡-缺卡提醒'
|
||||
]"
|
||||
:key="index"
|
||||
class="my-1.5 bg-[#F6F8FC] w-4.8/10 py-3.5 px-2 rounded-2.2 box-border flex flex-row items-center"
|
||||
>
|
||||
<image src="/static/images/icon_wechat.png" class="w-5 h-5" mode="scaleToFill" />
|
||||
<view class="text-center text-2.5 custom-color-black ml-1">{{ item }}</view>
|
||||
<wd-icon name="arrow-right" class="text-gray flex-1 text-right" size="20"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { TabBarItem } from '@/typings'
|
||||
|
||||
const list = ref<Array<TabBarItem>>([
|
||||
{
|
||||
title: '首页',
|
||||
isDot: true,
|
||||
icon: 'home'
|
||||
},
|
||||
{
|
||||
title: '我的',
|
||||
value: 0,
|
||||
icon: '/static/tabbar/home.png'
|
||||
},
|
||||
{
|
||||
title: '最大值',
|
||||
value: 200,
|
||||
icon: '/static/tabbar/home.png'
|
||||
},
|
||||
{
|
||||
title: '客服',
|
||||
value: 3,
|
||||
icon: '/static/tabbar/home.png'
|
||||
}
|
||||
])
|
||||
function goAddGroup() {
|
||||
// todo goAddGroup
|
||||
console.log('goAddGroup')
|
||||
uni.navigateTo({
|
||||
url: '/pages/attendance/attendance-add-group/attendance-add-group'
|
||||
})
|
||||
}
|
||||
const goClasses = () => {
|
||||
console.log('goClasses')
|
||||
uni.navigateTo({
|
||||
url: '/pages/attendance/classes-manage'
|
||||
})
|
||||
}
|
||||
const goIssueRecord = () => {
|
||||
console.log('goIssueRecord')
|
||||
uni.navigateTo({
|
||||
url: '/pages/attendance/issue-record'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
@ -1,113 +0,0 @@
|
||||
<route lang="json5" type="page">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<view class="flex flex-col flex-1">
|
||||
<wd-tabs v-model="tabIndex" color="#3372FA" inactiveColor="gray">
|
||||
<block v-for="item in tabs" :key="item">
|
||||
<wd-tab :title="item"></wd-tab>
|
||||
</block>
|
||||
</wd-tabs>
|
||||
<view v-if="tabIndex == 0" class="flex-1 flex flex-col px-3 pt-4">
|
||||
<view class="flex flex-row items-center">
|
||||
<wd-icon name="arrow-left" class="text-gray" size="20"></wd-icon>
|
||||
<view class="w-30 text-center">
|
||||
{{ new Date(teamDateTime).getFullYear() }}年{{ new Date(teamDateTime).getMonth() + 1 }}月
|
||||
</view>
|
||||
<wd-icon name="arrow-right" class="text-gray" size="20"></wd-icon>
|
||||
<view class="color-[#3372FA] flex-1 text-end text-3">查看/导出月报</view>
|
||||
</view>
|
||||
<view class="rounded-2 bg-white mt-4 p-3.5 flex flex-col">
|
||||
<wd-calendar-view
|
||||
v-model="teamDateTime"
|
||||
@change="handleChange"
|
||||
:min-date="new Date(new Date().getFullYear(), new Date().getMonth(), 1).getTime()"
|
||||
:max-date="new Date(new Date().getFullYear(), new Date().getMonth() + 1, 0).getTime()"
|
||||
/>
|
||||
<view class="h-px bg-gray-300 my-4"></view>
|
||||
<wd-circle
|
||||
class="flex flex-row flex-justify-center mt-2"
|
||||
v-model="current"
|
||||
:size="100"
|
||||
:strokeWidth="20"
|
||||
></wd-circle>
|
||||
<view class="text-5 font-500 text-center mt-3">0/13</view>
|
||||
<view class="text-3 color-gray text-center">打卡人数/应到人数</view>
|
||||
<view class="flex flex-row flex-justify-between mt-4 mx-5">
|
||||
<view v-for="(item, index) in statusList" :key="index" class="flex flex-col items-center">
|
||||
<view class="font-bold">{{ item.value }}</view>
|
||||
<view class="text-3 color-gray">{{ item.name }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="w-100% h-17 bg-blue mt-2 rounded-2" @click="goCheck"></view>
|
||||
<view class="w-100% h-17 bg-gray mt-2 rounded-2" @click="goProblem"></view>
|
||||
</view>
|
||||
<view v-if="tabIndex == 1" class="flex-1 flex flex-col px-3 pt-4">
|
||||
<view class="flex flex-row items-center">
|
||||
<wd-icon name="arrow-left" class="text-gray" size="20"></wd-icon>
|
||||
<view class="w-30 text-center">
|
||||
{{ new Date(teamDateTime).getFullYear() }}年{{ new Date(teamDateTime).getMonth() + 1 }}月
|
||||
</view>
|
||||
<wd-icon name="arrow-right" class="text-gray" size="20"></wd-icon>
|
||||
<view class="color-[#3372FA] flex-1 text-end text-3">查看月报</view>
|
||||
</view>
|
||||
<view class="rounded-2 bg-white mt-4 p-3.5 flex flex-col">
|
||||
<wd-calendar-view
|
||||
v-model="myDateTime"
|
||||
@change="handleChange"
|
||||
:min-date="new Date(new Date().getFullYear(), new Date().getMonth(), 1).getTime()"
|
||||
:max-date="new Date(new Date().getFullYear(), new Date().getMonth() + 1, 0).getTime()"
|
||||
/>
|
||||
<view class="h-px bg-gray-300 my-4"></view>
|
||||
<view class="flex flex-row flex-justify-between items-center">
|
||||
<view class="text-4 font-500 text-center">
|
||||
{{ new Date(myDateTime).getFullYear() }}年{{ new Date(myDateTime).getMonth() + 1 }}月{{
|
||||
new Date(myDateTime).getDate()
|
||||
}}日
|
||||
</view>
|
||||
<view class="color-gray text-3">休息</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
//
|
||||
const tabs = ['团队统计', '我的统计']
|
||||
const statusList = ref([
|
||||
{ name: '未打卡', value: 13 },
|
||||
{ name: '迟到', value: 0 },
|
||||
{ name: '请假', value: 0 }
|
||||
])
|
||||
const tabIndex = ref(0)
|
||||
const teamDateTime = ref(Date.now())
|
||||
const myDateTime = ref(Date.now())
|
||||
const current = ref<number>(17)
|
||||
function handleChange({ value }) {
|
||||
console.log(value)
|
||||
}
|
||||
function goCheck() {
|
||||
console.log('goCheck')
|
||||
}
|
||||
function goProblem() {
|
||||
console.log('goProblem')
|
||||
}
|
||||
onMounted(() => {
|
||||
console.log('mounted')
|
||||
current.value = Math.random() * 100
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wd-circle {
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
@ -1,85 +0,0 @@
|
||||
<route lang="json5" type="page">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<view class="flex flex-col h-100vh">
|
||||
<TopNavigation title="打卡时间限制"></TopNavigation>
|
||||
<view class="bg-[#E2EAFA] px-3 py-2 color-[#3372FA] text-3.3">
|
||||
可设置每次上下班是否需要打卡、允许打卡的时间范围
|
||||
</view>
|
||||
<scroll-view scroll-y class="flex-1">
|
||||
<view class="" v-for="(item, index) in times" :key="index">
|
||||
<view class="color-gray text-3.3 p-3">上班时间段{{ index + 1 }}</view>
|
||||
<view class="bg-white" v-for="(t, i) in item.times" :key="i">
|
||||
<CommonItem :text="'上班' + t" :isNext="false" hint="" noLine>
|
||||
<template v-slot:child>
|
||||
<wd-switch v-model="item.switch[i]" class="ml-a" />
|
||||
</template>
|
||||
</CommonItem>
|
||||
<view class="flex flex-row flex-justify-between mx-4">
|
||||
<view class="bg-[#f6f8fc] rounded-2 p-2 w-48% box-border">
|
||||
<view class="text-2.8 color-gray">最早打卡时间</view>
|
||||
<view class="flex flex-row items-center mt-1.5">
|
||||
<view class="color-[#3372FA] text-3">未设置</view>
|
||||
<view class="i-carbon-next-outline ml-1 text-2.3 color-gray"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bg-[#f6f8fc] rounded-2 p-2 w-48% box-border">
|
||||
<view class="text-2.8 color-gray">最早打卡时间</view>
|
||||
<view class="flex flex-row items-center mt-1.5">
|
||||
<view class="color-[#3372FA] text-3">未设置</view>
|
||||
<view class="i-carbon-next-outline ml-1 text-2.3 color-gray"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
:class="i != item.times.length - 1 ? '' : 'invisible'"
|
||||
class="hpx mx-4 mt-3 bg-gray-200"
|
||||
></view>
|
||||
</view>
|
||||
<!-- <view v-if="index == times.length - 1">若未设置,</view>s -->
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="mt-a w-full p-3 box-border border-solid border-0 border-t-1 border-gray-200">
|
||||
<wd-button :round="false" block>保存</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import CommonItem from '@/components/CommonItemItem/CommonItem.vue'
|
||||
|
||||
const times = ref([
|
||||
{
|
||||
times: ['07:00', '09:00'],
|
||||
switch: [true, false]
|
||||
},
|
||||
{
|
||||
times: ['07:00', '09:00'],
|
||||
switch: [true, false]
|
||||
},
|
||||
{
|
||||
times: ['07:00', '09:00'],
|
||||
switch: [true, false]
|
||||
},
|
||||
{
|
||||
times: ['07:00', '09:00'],
|
||||
switch: [true, false]
|
||||
},
|
||||
{
|
||||
times: ['07:00', '09:00'],
|
||||
switch: [true, false]
|
||||
}
|
||||
])
|
||||
//
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
//
|
||||
</style>
|
||||
@ -1,233 +0,0 @@
|
||||
<route lang="json5" type="page">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<BottomPop
|
||||
:show="showType"
|
||||
title="考勤类型"
|
||||
:onclose="
|
||||
() => {
|
||||
showType = false
|
||||
typeIndex = typeSelectIndex
|
||||
}
|
||||
"
|
||||
:onSure="
|
||||
() => {
|
||||
typeSelectIndex = typeIndex
|
||||
}
|
||||
"
|
||||
>
|
||||
<template v-slot:child>
|
||||
<view class="px-4">
|
||||
<view
|
||||
class="bg-white rounded-2 mt-2"
|
||||
@click="typeIndex = index"
|
||||
v-for="(item, index) in typeList"
|
||||
:key="index"
|
||||
>
|
||||
<view class="flex flex-row items-center p-3 box-border">
|
||||
<view class="flex flex-1 flex-col flex-justify-items-start">
|
||||
<view class="">{{ item.title }}</view>
|
||||
<view class="mt-1 text-3.3">{{ item.desc }}</view>
|
||||
<view class="mt-1 text-2.8 color-gray">{{ item.desc2 }}</view>
|
||||
</view>
|
||||
<view v-show="typeIndex == index">
|
||||
<wd-icon name="check" class="color-[#3372FA] mr-2"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</BottomPop>
|
||||
|
||||
<BottomPop
|
||||
:show="showWay"
|
||||
title="打卡方式选择"
|
||||
:onclose="
|
||||
() => {
|
||||
showWay = false
|
||||
}
|
||||
"
|
||||
noSure
|
||||
>
|
||||
<template v-slot:child>
|
||||
<view class="px-4">
|
||||
<view class="bg-white rounded-2 mt-2">
|
||||
<view
|
||||
class="flex flex-row items-center p-3 box-border"
|
||||
@click="
|
||||
() => {
|
||||
wayIndex = index
|
||||
showWay = false
|
||||
}
|
||||
"
|
||||
v-for="(item, index) in wayList"
|
||||
:key="index"
|
||||
>
|
||||
<view class="flex flex-1 flex-col flex-justify-items-start">
|
||||
<view class="">{{ item.title }}</view>
|
||||
<view class="mt-1 text-2.8 color-gray">{{ item.desc }}</view>
|
||||
</view>
|
||||
<view v-show="wayIndex == index">
|
||||
<wd-icon name="check" class="color-[#3372FA] mr-2"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</BottomPop>
|
||||
|
||||
<TopNavigation title="添加考勤组"></TopNavigation>
|
||||
<view class="h-[calc(100vh-60px)] p-3 box-border">
|
||||
<view class="bg-white rounded-2.2 mt-2">
|
||||
<CommonItem text="考勤组名称" isMust :isNext="false" value="" hint="" noLine></CommonItem>
|
||||
<view class="flex items-center px-4.3 pb-3 box-border">
|
||||
<input
|
||||
class="w-100%"
|
||||
v-model="name"
|
||||
placeholder="必填"
|
||||
placeholder-class="color-gray"
|
||||
:maxlength="15"
|
||||
@input="nameInput"
|
||||
/>
|
||||
<view
|
||||
@click="name = ''"
|
||||
v-show="name"
|
||||
class="i-carbon-close-filled color-gray text-4"
|
||||
></view>
|
||||
<view class="text-3 self-center color-gray ml-1">{{ name.length }}/{{ 15 }}</view>
|
||||
</view>
|
||||
<view class="hpx bg-gray-100 mx-2.5"></view>
|
||||
<CommonItem
|
||||
@click="
|
||||
() => {
|
||||
showType = true
|
||||
}
|
||||
"
|
||||
text="考勤类型"
|
||||
noLine
|
||||
:value="typeList[typeSelectIndex].title"
|
||||
></CommonItem>
|
||||
</view>
|
||||
<view class="bg-white rounded-2.2 mt-2">
|
||||
<CommonItem @click="goStaff()" text="考勤人员" isMust value=""></CommonItem>
|
||||
<CommonItem
|
||||
@click="goTime()"
|
||||
text="考勤时间"
|
||||
noLine
|
||||
value="周一至周五,09:00-17:00"
|
||||
></CommonItem>
|
||||
</view>
|
||||
<view class="bg-white rounded-2.2 mt-2">
|
||||
<CommonItem
|
||||
@click="
|
||||
() => {
|
||||
showWay = true
|
||||
}
|
||||
"
|
||||
text="打卡方式"
|
||||
:value="wayList[wayIndex].title"
|
||||
></CommonItem>
|
||||
<CommonItem
|
||||
@click="goDevice"
|
||||
text="打卡设备"
|
||||
:isMust="wayIndex == 0"
|
||||
:noLine="wayIndex == 0"
|
||||
value=""
|
||||
hint="未选择"
|
||||
></CommonItem>
|
||||
<CommonItem text="打卡地点" v-show="wayIndex == 1" value="" hint="未设置"></CommonItem>
|
||||
<CommonItem text="打卡WIFI" v-show="wayIndex == 1" noLine value="" hint="未设置"></CommonItem>
|
||||
</view>
|
||||
<view @click="goOutsideRule()" v-show="wayIndex == 1" class="bg-white rounded-2.2 mt-2">
|
||||
<CommonItem text="外勤规则" noLine value="允许外勤卡" hint=""></CommonItem>
|
||||
</view>
|
||||
<view class="bg-white rounded-2.2 mt-2">
|
||||
<CommonItem text="加班统计规则" noLine value="未开启" hint=""></CommonItem>
|
||||
</view>
|
||||
<view
|
||||
class="fixed bottom-0 left-0 w-full p-3 box-border border-solid border-0 border-t-1 border-gray-200"
|
||||
>
|
||||
<wd-button :round="false" block>保存</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import BottomPop from '@/components/BottomPop/BottomPop.vue'
|
||||
import CommonItem from '@/components/CommonItemItem/CommonItem.vue'
|
||||
const showType = ref(true)
|
||||
const typeIndex = ref(0)
|
||||
const typeSelectIndex = ref(0)
|
||||
const showWay = ref(false)
|
||||
const wayIndex = ref(0)
|
||||
const name = ref('')
|
||||
const nameInput = () => {
|
||||
console.log(name.value)
|
||||
}
|
||||
const typeList = [
|
||||
{
|
||||
title: '固定班制',
|
||||
desc: '人员每周按照相同时间上下班',
|
||||
desc2: '适用于办公室坐班,例如每周一至五上班,朝9晚5'
|
||||
},
|
||||
{
|
||||
title: '自由班制',
|
||||
desc: '无固定上下班时间,可随时打卡',
|
||||
desc2: '适用于计时工种、灵活用工等'
|
||||
},
|
||||
{
|
||||
title: '排班制',
|
||||
desc: '排班制人员按每日所排班次上下班',
|
||||
desc2: '适用于工厂、门店等,例如三班倒、做—休一'
|
||||
}
|
||||
]
|
||||
const wayList = [
|
||||
{
|
||||
title: '设备打卡',
|
||||
desc: '适用于内勤打卡,有效避免打卡等作弊行为'
|
||||
},
|
||||
{
|
||||
title: '设备+手机打卡',
|
||||
desc: '选择后可开启外勤打卡'
|
||||
}
|
||||
]
|
||||
const outsideRule = {
|
||||
allow: false,
|
||||
takePhoto: false,
|
||||
remark: false,
|
||||
selectPhoto: false
|
||||
}
|
||||
const goOutsideRule = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/attendance/attendance-add-group/outside-rules'
|
||||
})
|
||||
}
|
||||
const goStaff = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/attendance/attendance-add-group/attendance-staff'
|
||||
})
|
||||
}
|
||||
const goTime = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/attendance/attendance-add-group/attendance-time'
|
||||
})
|
||||
}
|
||||
const goDevice = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/attendance/attendance-add-group/attendance-device'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
background-color: #f6f8fc;
|
||||
}
|
||||
</style>
|
||||
@ -1,131 +0,0 @@
|
||||
<route lang="json5" type="page">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<view class="h-100vh flex flex-col">
|
||||
<TopNavigation title="选择考勤机/门禁点"></TopNavigation>
|
||||
<view class="bg-white flex flex flex-row flex-justify-center items-center rounded-1 m-3 p-1.5">
|
||||
<wd-icon name="search" class="color-gray text-3.3 ml-2"></wd-icon>
|
||||
<view class="color-gray ml-2">搜索</view>
|
||||
</view>
|
||||
<view class="m-3 mt-2 color-gray">全部</view>
|
||||
<scroll-view scroll-y>
|
||||
<view
|
||||
v-for="(device, index) in deviceList"
|
||||
:key="index"
|
||||
class="bg-white px-3 py-2 flex flex-row items-center border-solid border-0 border-t-1 border-gray-100"
|
||||
>
|
||||
<view
|
||||
@click="
|
||||
() => {
|
||||
device.isSelect = !device.isSelect
|
||||
if (device.isSelect) {
|
||||
selectList.push(device)
|
||||
} else {
|
||||
selectList = selectList.filter(item => item.id !== device.id)
|
||||
}
|
||||
}
|
||||
"
|
||||
class="text-5"
|
||||
:class="
|
||||
device.isSelect
|
||||
? 'i-carbon-checkmark-filled color-[#3372FA]'
|
||||
: 'i-carbon-circle-outline color-gray'
|
||||
"
|
||||
></view>
|
||||
<image src="/static/images/icon_one_key_door.png" mode="aspectFit" class="h-9 w-11" />
|
||||
<view>{{ device.name }}</view>
|
||||
<view class="ml-a color-gray">{{ device.type }}</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="flex p-3 box-border border-solid border-0 border-t-1 border-gray-200 items-center">
|
||||
<view
|
||||
class="items-center flex flex-1"
|
||||
:style="selectList.length != 0 ? '' : 'visibility: hidden;'"
|
||||
>
|
||||
<view class="color-[#3372FA]">已选中:{{ selectList.length }}个</view>
|
||||
<view class="i-carbon-chevron-right color-[#3372FA] ml-2"></view>
|
||||
</view>
|
||||
<wd-button class="ml-a" :round="false">确定</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
const selectList = ref([])
|
||||
const deviceList = ref([
|
||||
{
|
||||
name: 'DK-K(L40231232)',
|
||||
id: 0,
|
||||
type: '公共门',
|
||||
isSelect: false
|
||||
},
|
||||
{
|
||||
name: 'DK-K(L40231233)',
|
||||
id: 1,
|
||||
type: '公共门',
|
||||
isSelect: false
|
||||
},
|
||||
{
|
||||
name: 'DK-K(L40231234)',
|
||||
id: 2,
|
||||
type: '公共门',
|
||||
isSelect: false
|
||||
},
|
||||
{
|
||||
name: 'DK-K(L40231235)',
|
||||
id: 3,
|
||||
type: '公共门',
|
||||
isSelect: false
|
||||
},
|
||||
{
|
||||
name: 'DK-K(L40231236)',
|
||||
id: 4,
|
||||
type: '公共门',
|
||||
isSelect: false
|
||||
},
|
||||
{
|
||||
name: 'DK-K(L40231237)',
|
||||
id: 5,
|
||||
type: '公共门',
|
||||
isSelect: false
|
||||
},
|
||||
{
|
||||
name: 'DK-K(L40231238)',
|
||||
id: 6,
|
||||
type: '公共门',
|
||||
isSelect: false
|
||||
},
|
||||
{
|
||||
name: 'DK-K(L40231239)',
|
||||
id: 7,
|
||||
type: '公共门',
|
||||
isSelect: false
|
||||
},
|
||||
{
|
||||
name: 'DK-K(L40231240)',
|
||||
id: 8,
|
||||
type: '公共门',
|
||||
isSelect: false
|
||||
},
|
||||
{
|
||||
name: 'DK-K(L40231241)',
|
||||
id: 9,
|
||||
type: '公共门',
|
||||
isSelect: false
|
||||
}
|
||||
|
||||
// Add more devices as needed
|
||||
])
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
//
|
||||
</style>
|
||||
@ -1,28 +0,0 @@
|
||||
<route lang="json5" type="page">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<TopNavigation title="考勤人员"></TopNavigation>
|
||||
<view class="h-[calc(100vh-60px)] p-3 box-border">
|
||||
<view class="bg-white flex flex flex-row flex-justify-center items-center rounded-2 py-1.5">
|
||||
<wd-icon name="search" class="color-gray text-3.3 ml-2"></wd-icon>
|
||||
<view class="color-gray ml-2">搜索</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
//
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
background-color: #f6f8fc;
|
||||
}
|
||||
</style>
|
||||
@ -1,172 +0,0 @@
|
||||
<route lang="json5" type="page">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<BottomPop
|
||||
:show="showHoliday"
|
||||
title="请选择"
|
||||
:onclose="
|
||||
() => {
|
||||
showHoliday = false
|
||||
}
|
||||
"
|
||||
noSure
|
||||
>
|
||||
<template v-slot:child>
|
||||
<view class="px-4">
|
||||
<view class="bg-white rounded-2 mt-2">
|
||||
<view
|
||||
class="flex flex-row items-center p-3 box-border"
|
||||
@click="
|
||||
() => {
|
||||
holidayIndex = index
|
||||
showHoliday = false
|
||||
}
|
||||
"
|
||||
v-for="(item, index) in holidayList"
|
||||
:key="index"
|
||||
>
|
||||
<view class="flex flex-1 flex-col flex-justify-items-start">
|
||||
<view class="">{{ item.title }}</view>
|
||||
</view>
|
||||
<view v-show="holidayIndex == index">
|
||||
<wd-icon name="check" class="color-[#3372FA] mr-2"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</BottomPop>
|
||||
<view class="h-100vh flex flex-col">
|
||||
<TopNavigation title="考勤时间"></TopNavigation>
|
||||
<scroll-view scroll-y class="px-4 box-border flex-1">
|
||||
<view v-for="(item, index) in rules" :key="index">
|
||||
<view class="flex flex-justify-between items-center mx-3.5 pb-2 pt-5">
|
||||
<view class="color-gray text-3">规则{{ index + 1 }}</view>
|
||||
<view @click="rules.splice(index, 1)" v-show="rules.length > 1" class="text-3 color-red">
|
||||
删除
|
||||
</view>
|
||||
</view>
|
||||
<view class="bg-white rounded-2 p-3.5">
|
||||
<view class="must mb-2">周时间选择</view>
|
||||
<view class="flex flex-row flex-justify-between">
|
||||
<view
|
||||
@click="checkOtherRule(t, i)"
|
||||
:class="t.isSelect ? selectCss : noSelectCss"
|
||||
v-for="(t, i) in item.dayList"
|
||||
:key="i"
|
||||
>
|
||||
{{ t.name }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="hpx bg-gray-100 my-3"></view>
|
||||
<view class="flex" @click="goSelectClasses">
|
||||
<view class="must flex-1">上下班时间</view>
|
||||
<view class="color-gray">{{ item.title }} {{ item.time }}</view>
|
||||
<wd-icon name="arrow-right ml-1.5 mr-0.5" class="text-gray" size="20"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
v-show="rules.length < 7"
|
||||
@click="rules.push({ dayList: cloneDayList(), title: '', time: '' })"
|
||||
class="flex flex-justify-center items-center flex-row py-3 box-border bg-white rounded-2 mt-2"
|
||||
>
|
||||
<wd-icon name="add-circle mr-2" class="color-[#3372FA]" size="17"></wd-icon>
|
||||
<view class="color-[#3372FA]">添加规则</view>
|
||||
</view>
|
||||
<view class="flex flex-justify-between items-center mx-3.5 pb-2 pt-5 color-gray text-3">
|
||||
特殊规则
|
||||
</view>
|
||||
<view class="bg-white rounded-2">
|
||||
<CommonItem text="节假日自动排休" value="" hint="" :isNext="false">
|
||||
<template v-slot:child>
|
||||
<wd-switch v-model="isAutoRest" class="ml-a"></wd-switch>
|
||||
</template>
|
||||
</CommonItem>
|
||||
<CommonItem
|
||||
v-show="isAutoRest"
|
||||
@click="showHoliday = true"
|
||||
text="节假日计划"
|
||||
value="按中国大陆法定节假日"
|
||||
hint=""
|
||||
></CommonItem>
|
||||
<CommonItem @click="goSpecial" text="特殊日期" value="已设置" hint="" noLine></CommonItem>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="mt-a w-full p-3 box-border border-solid border-0 border-t-1 border-gray-200">
|
||||
<wd-button :round="false" block>保存</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import CommonItem from '@/components/CommonItemItem/CommonItem.vue'
|
||||
|
||||
const baseCss = 'rounded-100 w-8 h-8 flex items-center justify-center font-bold text-3 border'
|
||||
const selectCss = `${baseCss} bg-[#3372FA] color-white border-[#3372FA] border-solid`
|
||||
const noSelectCss = `${baseCss} border-gray border-dashed`
|
||||
const isAutoRest = ref(false)
|
||||
const showHoliday = ref(false)
|
||||
const holidayIndex = ref(0)
|
||||
const holidayList = [{ title: '按中国大陆法定节假日' }]
|
||||
const dayList = [
|
||||
{ name: '一', value: 1, isSelect: false },
|
||||
{ name: '二', value: 2, isSelect: false },
|
||||
{ name: '三', value: 3, isSelect: false },
|
||||
{ name: '四', value: 4, isSelect: false },
|
||||
{ name: '五', value: 5, isSelect: false },
|
||||
{ name: '六', value: 6, isSelect: false },
|
||||
{ name: '日', value: 7, isSelect: false }
|
||||
]
|
||||
const cloneDayList = () => {
|
||||
return dayList.map(day => ({ ...day }))
|
||||
}
|
||||
|
||||
const rules = ref([
|
||||
{
|
||||
dayList: cloneDayList(),
|
||||
title: '默认班次',
|
||||
time: '09:00-17:00'
|
||||
}
|
||||
])
|
||||
const checkOtherRule = (t, i) => {
|
||||
if (!t.isSelect) {
|
||||
rules.value.forEach(item => {
|
||||
item.dayList[i].isSelect = false
|
||||
})
|
||||
}
|
||||
t.isSelect = !t.isSelect
|
||||
}
|
||||
const goSelectClasses = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/attendance/classes-manage?isSelect=true'
|
||||
})
|
||||
// goSelectClass
|
||||
}
|
||||
const goSpecial = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/attendance/attendance-add-group/special-date-set'
|
||||
})
|
||||
}
|
||||
//
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.must {
|
||||
position: relative;
|
||||
&::before {
|
||||
position: absolute;
|
||||
left: -1em;
|
||||
color: red;
|
||||
content: '*';
|
||||
}
|
||||
}
|
||||
//
|
||||
</style>
|
||||
@ -1,61 +0,0 @@
|
||||
<route lang="json5" type="page">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<TopNavigation title="外勤规则"></TopNavigation>
|
||||
<view class="h-[calc(100vh-60px)] p-3 box-border">
|
||||
<view class="bg-white rounded-2.2">
|
||||
<CommonItem text="允许外勤打卡" noLine value="">
|
||||
<template v-slot:child>
|
||||
<wd-switch v-model="outsideRules.allow" class="ml-a" />
|
||||
</template>
|
||||
</CommonItem>
|
||||
</view>
|
||||
<view v-show="outsideRules.allow" class="bg-white rounded-2.2 mt-2">
|
||||
<CommonItem text="外勤打卡必须拍照" value="">
|
||||
<template v-slot:child>
|
||||
<wd-switch v-model="outsideRules.takePhoto" class="ml-a" />
|
||||
</template>
|
||||
</CommonItem>
|
||||
<CommonItem text="外勤卡必须填写备注" value="">
|
||||
<template v-slot:child>
|
||||
<wd-switch v-model="outsideRules.remark" class="ml-a" />
|
||||
</template>
|
||||
</CommonItem>
|
||||
<CommonItem text="允许从手机相册选择照片" noLine value="">
|
||||
<template v-slot:child>
|
||||
<wd-switch v-model="outsideRules.selectPhoto" class="ml-a" />
|
||||
</template>
|
||||
</CommonItem>
|
||||
</view>
|
||||
<view
|
||||
class="fixed bottom-0 left-0 w-full p-3 box-border border-solid border-0 border-t-1 border-gray-200"
|
||||
>
|
||||
<wd-button :round="false" block>保存</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import CommonItem from '@/components/CommonItemItem/CommonItem.vue'
|
||||
import { OutsideRules } from '@/typings'
|
||||
const checked = ref(false)
|
||||
const outsideRules = ref<OutsideRules>({
|
||||
allow: false,
|
||||
takePhoto: false,
|
||||
remark: false,
|
||||
selectPhoto: false
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
background-color: #f6f8fc;
|
||||
}
|
||||
</style>
|
||||
@ -1,90 +0,0 @@
|
||||
<route lang="json5" type="page">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<view class="h-100vh flex flex-col">
|
||||
<TopNavigation title="特殊日期"></TopNavigation>
|
||||
<wd-tabs v-model="tabsIndex">
|
||||
<block v-for="item in tabs" :key="item">
|
||||
<wd-tab :title="item.title"></wd-tab>
|
||||
</block>
|
||||
</wd-tabs>
|
||||
<scroll-view scroll-y class="flex-1 box-border p-3">
|
||||
<view class="bg-white rounded-2">
|
||||
<CommonItem
|
||||
text="添加"
|
||||
@click="
|
||||
tabsIndex == 0 ? mustDate.push(cloneBestDate()) : unMustDate.push(cloneBestDate())
|
||||
"
|
||||
>
|
||||
<template v-slot:child>
|
||||
<wd-icon name="add-circle" class="ml-a" size="18"></wd-icon>
|
||||
</template>
|
||||
</CommonItem>
|
||||
</view>
|
||||
<view
|
||||
class="mt-5"
|
||||
v-for="(item, index) in tabsIndex == 0 ? mustDate : unMustDate"
|
||||
:key="index"
|
||||
>
|
||||
<view class="flex flex-justify-between px-3 mb-2">
|
||||
<view class="color-gray text-3">{{ tabs[tabsIndex].title }} ({{ index + 1 }})</view>
|
||||
<view
|
||||
@click="tabsIndex == 0 ? mustDate.splice(index, 1) : unMustDate.splice(index, 1)"
|
||||
class="color-red text-3"
|
||||
>
|
||||
删除
|
||||
</view>
|
||||
</view>
|
||||
<view class="bg-white rounded-2">
|
||||
<CommonItem text="日期" :value="item.data" :noLine="tabsIndex != 0"></CommonItem>
|
||||
<CommonItem
|
||||
v-show="tabsIndex == 0"
|
||||
text="上下班时间"
|
||||
:value="item.time"
|
||||
noLine
|
||||
></CommonItem>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="mt-a w-full p-3 box-border border-solid border-0 border-t-1 border-gray-200">
|
||||
<wd-button :round="false" block>确定</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import CommonItem from '@/components/CommonItemItem/CommonItem.vue'
|
||||
|
||||
const tabsIndex = ref(0)
|
||||
const mustDate = ref([])
|
||||
const unMustDate = ref([])
|
||||
const bestDate = [
|
||||
{
|
||||
date: '',
|
||||
time: ''
|
||||
}
|
||||
]
|
||||
const cloneBestDate = () => {
|
||||
return bestDate.map(t => ({ ...t }))
|
||||
}
|
||||
const tabs = ref([
|
||||
{
|
||||
title: '必须打卡的日期'
|
||||
},
|
||||
{
|
||||
title: '不用打卡的日期'
|
||||
}
|
||||
])
|
||||
//
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
//
|
||||
</style>
|
||||
@ -1,42 +0,0 @@
|
||||
<route lang="json5" type="page">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<view class="h-100vh flex flex-col">
|
||||
<TopNavigation title="考勤规则"></TopNavigation>
|
||||
<view class="px-4 pt-5 text-3">
|
||||
<view class="color-gray text-3 ml-3.5 mb-2">考勤</view>
|
||||
<view class="bg-white rounded-2 p-3.5">
|
||||
<view class="font-bold text-3.5">今日考勤时间</view>
|
||||
<view class="mt-3">上班时间不固定,可自由打卡</view>
|
||||
</view>
|
||||
<view class="bg-white rounded-2 p-3.5 mt-2">
|
||||
<view class="font-bold text-3.5">打卡方式</view>
|
||||
<view class="mt-3">在设备上打卡</view>
|
||||
<view class="mt-2">手机定位打卡</view>
|
||||
<view class="inline-flex flex-row items-center bg-gray-100 rounded-2 mt-1.5 p-1.5">
|
||||
<view class="i-carbon-location-filled color-[#3372FA]"></view>
|
||||
<view class="ml-0.5 text-3">宏发科技园H1栋</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bg-white rounded-2 p-3.5 mt-2">
|
||||
<view class="font-bold text-3.5">其他</view>
|
||||
<view class="mt-3">允许外勤打卡</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
//
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
//
|
||||
</style>
|
||||
@ -1,53 +0,0 @@
|
||||
<route lang="json5" type="page">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<view class="h-[calc(100vh-50px)] flex flex-col">
|
||||
<TopNavigation :title="titleTab[curIndex]"></TopNavigation>
|
||||
<scroll-view class="flex-1 box-border" scroll-y>
|
||||
<AttendanceClockIn v-show="curIndex === 0"></AttendanceClockIn>
|
||||
<AttendanceStatistics v-show="curIndex === 1"></AttendanceStatistics>
|
||||
<AttendanceSet v-show="curIndex === 2"></AttendanceSet>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<CustomTabBar :list="list" :default-index="0" @change="change"></CustomTabBar>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import AttendanceClockIn from './AttendanceClockIn.vue'
|
||||
import AttendanceStatistics from './AttendanceStatistics.vue'
|
||||
import AttendanceSet from './AttendanceSet.vue'
|
||||
import { TabBarItem } from '@/typings'
|
||||
const pages = [AttendanceClockIn, AttendanceStatistics, AttendanceSet]
|
||||
const titleTab = ['考勤打卡', '考勤统计', '设置']
|
||||
const list = ref<Array<TabBarItem>>([
|
||||
{
|
||||
title: '打卡',
|
||||
icon: 'home'
|
||||
},
|
||||
{
|
||||
title: '统计',
|
||||
icon: 'notification'
|
||||
},
|
||||
{
|
||||
title: '设置',
|
||||
icon: 'setting'
|
||||
}
|
||||
])
|
||||
const curIndex = ref(0)
|
||||
const change = (data: { value: number }) => {
|
||||
curIndex.value = data.value
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
background-color: #f6f8fc;
|
||||
}
|
||||
</style>
|
||||
@ -1,128 +0,0 @@
|
||||
<route lang="json5" type="page">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<view class="h-100vh flex flex-col">
|
||||
<TopNavigation title="新增班次"></TopNavigation>
|
||||
<view class="flex-1 p-3 box-border">
|
||||
<view class="bg-white rounded-2.2 mt-2">
|
||||
<CommonItem text="班次名称" isMust :isNext="false" value="" hint="" noLine></CommonItem>
|
||||
<view class="flex items-center px-4.3 pb-3 box-border">
|
||||
<input
|
||||
class="w-100%"
|
||||
v-model="name"
|
||||
placeholder="必填"
|
||||
placeholder-class="color-gray"
|
||||
:maxlength="8"
|
||||
/>
|
||||
<view
|
||||
@click="name = ''"
|
||||
v-show="name"
|
||||
class="i-carbon-close-filled color-gray text-4"
|
||||
></view>
|
||||
<view class="text-3 self-center color-gray ml-1">{{ name.length }}/{{ 8 }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-for="(item, index) in times" :key="index">
|
||||
<view class="flex items-center my-3 flex-justify-between text-3">
|
||||
<view class="color-gray ml-4.2">上下班时段{{ index + 1 }}</view>
|
||||
<view v-show="times.length > 1" @click="times.splice(index, 1)" class="color-red mr-4">
|
||||
删除
|
||||
</view>
|
||||
</view>
|
||||
<view class="bg-white rounded-2.2 mt-2">
|
||||
<CommonItem text="上班" value="09:00"></CommonItem>
|
||||
<CommonItem text="下班" value="17:00"></CommonItem>
|
||||
<view
|
||||
@click="times.push({ start: '09:00', end: '17:00' })"
|
||||
v-show="index == times.length - 1 && times.length < 3"
|
||||
class="flex flex-justify-center items-center flex-row py-4 box-border"
|
||||
>
|
||||
<wd-icon name="add-circle mr-2" class="color-[#3372FA]" size="17"></wd-icon>
|
||||
<view class="color-[#3372FA]">添加时段</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bg-white rounded-2.2 mt-2">
|
||||
<CommonItem @click="goAllowedTime" text="允许打卡时间" value="" hint=""></CommonItem>
|
||||
</view>
|
||||
<view class="bg-white rounded-2.2 mt-2">
|
||||
<CommonItem @click="goFlexblePunching" text="弹性打卡" value="" hint="不设置"></CommonItem>
|
||||
</view>
|
||||
<view v-show="times.length == 1" class="bg-white rounded-2.2 mt-2">
|
||||
<CommonItem value="" :noLine="haveRest ? false : true">
|
||||
<template v-slot:leftChild>
|
||||
<view>
|
||||
<view>休息时间</view>
|
||||
<view class="color-gray mt-1">中途休息时间不计入出勤时长</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-slot:child>
|
||||
<wd-switch v-model="haveRest" class="ml-a" />
|
||||
</template>
|
||||
</CommonItem>
|
||||
<CommonItem v-show="haveRest" text="休息开始时间" value="12:00"></CommonItem>
|
||||
<CommonItem v-show="haveRest" text="休息结束时间" value="13:00"></CommonItem>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
v-if="!isEdit"
|
||||
class="fixed bottom-0 left-0 w-full p-3 box-border border-solid border-0 border-t-1 border-gray-200"
|
||||
>
|
||||
<wd-button :round="false" block>保存</wd-button>
|
||||
</view>
|
||||
<view v-else class="flex flex-row flex-justify-between p-4">
|
||||
<view class="flex-1 mr-2">
|
||||
<wd-button
|
||||
size="large"
|
||||
custom-style="background:#E9EBEF;color:#3372FA"
|
||||
:round="false"
|
||||
block
|
||||
>
|
||||
删除
|
||||
</wd-button>
|
||||
</view>
|
||||
<view class="flex-1 ml-2">
|
||||
<wd-button size="large" :round="false" block>保存</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import CommonItem from '@/components/CommonItemItem/CommonItem.vue'
|
||||
onLoad(options => {
|
||||
isEdit.value = options.isEdit ?? false
|
||||
})
|
||||
const isEdit = ref(false)
|
||||
const name = ref('')
|
||||
const haveRest = ref(false)
|
||||
const times = ref([
|
||||
{
|
||||
start: '09:00',
|
||||
end: '17:00'
|
||||
}
|
||||
])
|
||||
|
||||
const goFlexblePunching = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/attendance/flexible-punching'
|
||||
})
|
||||
}
|
||||
const goAllowedTime = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/attendance/allowed-time'
|
||||
})
|
||||
}
|
||||
//
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
//
|
||||
</style>
|
||||
@ -1,158 +0,0 @@
|
||||
<route lang="json5" type="page">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<view class="h-100vh flex flex-col">
|
||||
<TopNavigation title="班次管理"></TopNavigation>
|
||||
<view class="flex items-center bg-gray-200 p-2 mx-3 rounded">
|
||||
<wd-icon name="search" class="text-gray mr-2"></wd-icon>
|
||||
<input
|
||||
v-model="key"
|
||||
type="text"
|
||||
placeholder="搜索班次名称"
|
||||
placeholder-class="text-gray"
|
||||
class="w-100%"
|
||||
/>
|
||||
<view v-show="key" class="i-carbon-close-filled color-gray text-4"></view>
|
||||
</view>
|
||||
<view @click="goClassesAddOrEdit(false)" class="bg-white rounded-2.2 mt-2 mx-3">
|
||||
<CommonItem text="添加班次" noLine value="">
|
||||
<template v-slot:child>
|
||||
<wd-icon name="add-circle" class="ml-a" size="20"></wd-icon>
|
||||
</template>
|
||||
</CommonItem>
|
||||
</view>
|
||||
<scroll-view
|
||||
ref="scrollView"
|
||||
scroll-y
|
||||
class="mt-2 flex-1 px-3 box-border"
|
||||
refresher-enabled
|
||||
@refresherrefresh="onRefresh()"
|
||||
:refresher-triggered="scrollViewStatus"
|
||||
>
|
||||
<view class="bg-white rounded-2.2">
|
||||
<CommonItem
|
||||
@click="selectIndex = index"
|
||||
v-for="(item, index) in classList"
|
||||
:key="index"
|
||||
value=""
|
||||
>
|
||||
<template v-slot:leftChild>
|
||||
<view class="flex items-center">
|
||||
<view
|
||||
v-if="isSelect"
|
||||
:class="
|
||||
selectIndex == index
|
||||
? 'i-carbon-checkmark-filled color-[#3372FA]'
|
||||
: 'i-carbon-circle-outline color-gray'
|
||||
"
|
||||
class="text-5 mr-3"
|
||||
></view>
|
||||
<view>
|
||||
<view>{{ item.name }}</view>
|
||||
<view class="color-gray mt-1">{{ item.time }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-slot:child>
|
||||
<view
|
||||
@click="goClassesAddOrEdit(true)"
|
||||
class="ml-a i-bytesize-compose color-gray"
|
||||
></view>
|
||||
</template>
|
||||
</CommonItem>
|
||||
</view>
|
||||
<view class="ml-3 mt-1 text-3 color-gray">添加班次后,请至考勤组中选择和使用</view>
|
||||
</scroll-view>
|
||||
<view
|
||||
v-if="isSelect"
|
||||
class="mt-a w-full p-3 box-border border-solid border-0 border-t-1 border-gray-200"
|
||||
>
|
||||
<wd-button :round="false" block>确定</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import CommonItem from '@/components/CommonItemItem/CommonItem.vue'
|
||||
const selectIndex = ref(-1)
|
||||
const isSelect = ref(false)
|
||||
const scrollViewStatus = ref(true)
|
||||
const key = ref('')
|
||||
const onRefresh = () => {
|
||||
console.log('refresh')
|
||||
scrollViewStatus.value = true
|
||||
setTimeout(() => {
|
||||
scrollViewStatus.value = false
|
||||
}, 500)
|
||||
}
|
||||
onLoad(options => {
|
||||
isSelect.value = options.isSelect ?? false
|
||||
})
|
||||
const goClassesAddOrEdit = (isEdit: boolean) => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/attendance/classes-add-edit?isEdit=' + isEdit
|
||||
})
|
||||
}
|
||||
|
||||
const classList = ref([
|
||||
{
|
||||
name: '默认班次',
|
||||
time: '09:00-17:00'
|
||||
},
|
||||
{
|
||||
name: '默认班次',
|
||||
time: '09:00-17:00'
|
||||
},
|
||||
{
|
||||
name: '默认班次',
|
||||
time: '09:00-17:00'
|
||||
},
|
||||
{
|
||||
name: '默认班次',
|
||||
time: '09:00-17:00'
|
||||
},
|
||||
{
|
||||
name: '默认班次',
|
||||
time: '09:00-17:00'
|
||||
},
|
||||
{
|
||||
name: '默认班次',
|
||||
time: '09:00-17:00'
|
||||
},
|
||||
{
|
||||
name: '默认班次',
|
||||
time: '09:00-17:00'
|
||||
},
|
||||
{
|
||||
name: '默认班次',
|
||||
time: '09:00-17:00'
|
||||
},
|
||||
{
|
||||
name: '默认班次',
|
||||
time: '09:00-17:00'
|
||||
},
|
||||
{
|
||||
name: '默认班次',
|
||||
time: '09:00-17:00'
|
||||
},
|
||||
{
|
||||
name: '默认班次',
|
||||
time: '09:00-17:00'
|
||||
}
|
||||
])
|
||||
|
||||
//
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
background-color: #f6f8fc;
|
||||
}
|
||||
</style>
|
||||
@ -1,80 +0,0 @@
|
||||
<route lang="json5" type="page">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<TopNavigation title="弹性打卡"></TopNavigation>
|
||||
<view class="bg-white rounded-2.2 mt-2">
|
||||
<CommonItem
|
||||
@click="selectIndex = index"
|
||||
v-for="(item, index) in setList"
|
||||
:key="index"
|
||||
:text="item.title"
|
||||
value=""
|
||||
hint=""
|
||||
:isNext="false"
|
||||
>
|
||||
<template v-slot:child>
|
||||
<view class="ml-a px-3 rounded-3 bg-[#F6F7FB] text-center">
|
||||
<wd-icon
|
||||
name="check"
|
||||
class="color-[#3372FA]"
|
||||
:class="selectIndex == index ? '' : 'invisible'"
|
||||
></wd-icon>
|
||||
</view>
|
||||
</template>
|
||||
</CommonItem>
|
||||
</view>
|
||||
<view class="bg-white rounded-2.2 mt-1.5">
|
||||
<CommonItem v-show="selectIndex == 1" text="" value="10分钟" hint="">
|
||||
<template v-slot:leftChild>
|
||||
<view>
|
||||
<view>上班最多可晚到</view>
|
||||
<view class="color-gray mt-1 text-3">晚到10分钟内不算迟到</view>
|
||||
</view>
|
||||
</template>
|
||||
</CommonItem>
|
||||
<CommonItem v-show="selectIndex == 1" text="" value="10分钟" hint="">
|
||||
<template v-slot:leftChild>
|
||||
<view>
|
||||
<view>上班最多可早走</view>
|
||||
<view class="color-gray mt-1 text-3">早走10分钟内不算迟到</view>
|
||||
</view>
|
||||
</template>
|
||||
</CommonItem>
|
||||
<CommonItem v-show="selectIndex == 2" text="最多晚到晚走" value="10分钟" hint=""></CommonItem>
|
||||
<CommonItem v-show="selectIndex == 2" text="最多早到早走" value="10分钟" hint=""></CommonItem>
|
||||
<view
|
||||
class="fixed bottom-0 left-0 w-full p-3 box-border border-solid border-0 border-t-1 border-gray-200"
|
||||
>
|
||||
<wd-button :round="false" block>确定</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import CommonItem from '@/components/CommonItemItem/CommonItem.vue'
|
||||
const setList = [
|
||||
{
|
||||
title: '不设置',
|
||||
isSelect: false
|
||||
},
|
||||
{
|
||||
title: '晚到、早走几分钟不记为异常',
|
||||
isSelect: false
|
||||
},
|
||||
{
|
||||
title: '允许晚到晚走、早到早走',
|
||||
isSelect: false
|
||||
}
|
||||
]
|
||||
const selectIndex = ref(-1)
|
||||
//
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
@ -1,152 +0,0 @@
|
||||
<route lang="json5" type="page">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<view class="h-100vh flex flex-col">
|
||||
<TopNavigation title="下发记录详情"></TopNavigation>
|
||||
<wd-tabs v-model="tabsIndex">
|
||||
<block v-for="item in tabs" :key="item">
|
||||
<wd-tab :title="`${item.title}(${item.num})`"></wd-tab>
|
||||
</block>
|
||||
</wd-tabs>
|
||||
|
||||
<view v-show="tabsIndex == 0" class="flex overflow-x-auto whitespace-nowrap mt-4">
|
||||
<view
|
||||
@click="tagIndex = index"
|
||||
v-for="(item, index) in tagList"
|
||||
:key="index"
|
||||
:class="tagIndex === index ? 'color-[#3372FA]' : ''"
|
||||
class="bg-white px-3 py-1.5 rounded-20 color-gray text-3 ml-3"
|
||||
>
|
||||
{{ item.name }}
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view scroll-y class="flex-1 p-3 box-border">
|
||||
<view v-for="(item, index) in detailList" :key="index" class="bg-white rounded-2 p-3 mb-2">
|
||||
<view class="flex flex-row flex-justify-between">
|
||||
<view>
|
||||
<view>{{ item.name }}</view>
|
||||
<view class="text-3 color-gray">{{ item.organization }}</view>
|
||||
</view>
|
||||
<view class="text-2.5 color-gray">{{ item.time }}</view>
|
||||
</view>
|
||||
<view class="hpx bg-gray-100 my-3"></view>
|
||||
<view class="flex flex-row items-center mt-1.5">
|
||||
<view class="i-carbon-virtual-machine text-3 color-gray"></view>
|
||||
<view class="w-15 ml-2.5 color-gray text-3">考勤机:</view>
|
||||
<view class="text-3">{{ item.machine }}</view>
|
||||
</view>
|
||||
<view class="flex flex-row items-center mt-1.5">
|
||||
<view class="i-carbon-virtual-machine text-3 color-gray"></view>
|
||||
<view class="w-15 ml-2.5 color-gray text-3">通行凭证:</view>
|
||||
<view class="text-3">{{ item.certificate }}</view>
|
||||
</view>
|
||||
<view class="flex flex-row items-center mt-1.5">
|
||||
<view class="i-carbon-virtual-machine text-3 color-gray"></view>
|
||||
<view class="w-15 ml-2.5 color-gray text-3">权限操作:</view>
|
||||
<view class="text-3">{{ item.operation }}</view>
|
||||
</view>
|
||||
<view v-if="tabsIndex == 0" class="flex flex-row items-center mt-1.5">
|
||||
<view class="i-carbon-virtual-machine text-3 color-gray"></view>
|
||||
<view class="w-15 ml-2.5 color-gray text-3">失败原因:</view>
|
||||
<view class="text-3 color-red">{{ item.fail }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const tagList = [
|
||||
{
|
||||
name: '全部'
|
||||
},
|
||||
{
|
||||
name: '人脸不符合要求'
|
||||
},
|
||||
{
|
||||
name: '设备离线'
|
||||
},
|
||||
{
|
||||
name: '设备未响应'
|
||||
},
|
||||
{
|
||||
name: '其他'
|
||||
}
|
||||
]
|
||||
const detailList = [
|
||||
{
|
||||
time: '2025-01-07 14:32:19',
|
||||
dec: '系统自动操作下发',
|
||||
name: 'HikMall_321312312',
|
||||
organization: '192312312的互联',
|
||||
machine: 'DS-K(L40231232)',
|
||||
certificate: '指纹1',
|
||||
operation: '下发权限',
|
||||
fail: '设备离线,请稍后再试'
|
||||
},
|
||||
{
|
||||
time: '2025-01-07 14:32:19',
|
||||
dec: '系统自动操作下发',
|
||||
name: 'HikMall_321312312',
|
||||
organization: '192312312的互联',
|
||||
machine: 'DS-K(L40231232)',
|
||||
certificate: '指纹1',
|
||||
operation: '下发权限',
|
||||
fail: '设备离线,请稍后再试'
|
||||
},
|
||||
{
|
||||
time: '2025-01-07 14:32:19',
|
||||
dec: '系统自动操作下发',
|
||||
name: 'HikMall_321312312',
|
||||
organization: '192312312的互联',
|
||||
machine: 'DS-K(L40231232)',
|
||||
certificate: '指纹1',
|
||||
operation: '下发权限',
|
||||
fail: '设备离线,请稍后再试'
|
||||
},
|
||||
{
|
||||
time: '2025-01-07 14:32:19',
|
||||
dec: '系统自动操作下发',
|
||||
name: 'HikMall_321312312',
|
||||
organization: '192312312的互联',
|
||||
machine: 'DS-K(L40231232)',
|
||||
certificate: '指纹1',
|
||||
operation: '下发权限',
|
||||
fail: '设备离线,请稍后再试'
|
||||
},
|
||||
{
|
||||
time: '2025-01-07 14:32:19',
|
||||
dec: '系统自动操作下发',
|
||||
name: 'HikMall_321312312',
|
||||
organization: '192312312的互联',
|
||||
machine: 'DS-K(L40231232)',
|
||||
certificate: '指纹1',
|
||||
operation: '下发权限',
|
||||
fail: '设备离线,请稍后再试'
|
||||
}
|
||||
]
|
||||
const tabs = [
|
||||
{
|
||||
title: '成功',
|
||||
num: detailList.length
|
||||
},
|
||||
{
|
||||
title: '失败',
|
||||
num: detailList.length
|
||||
}
|
||||
]
|
||||
const tagIndex = ref(0)
|
||||
const tabsIndex = ref(0)
|
||||
//
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
//
|
||||
</style>
|
||||
@ -1,126 +0,0 @@
|
||||
<route lang="json5" type="page">
|
||||
{
|
||||
layout: 'default',
|
||||
style: {
|
||||
navigationStyle: 'custom'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
||||
<template>
|
||||
<view class="h-100vh flex flex-col">
|
||||
<TopNavigation title="下发记录"></TopNavigation>
|
||||
<view class="bg-orange-100 p-2 color-orange text-3.3">
|
||||
此处仅展示考勤组中打卡设备的下发记录
|
||||
</view>
|
||||
<scroll-view scroll-y class="flex-1 p-3.5 box-border">
|
||||
<view
|
||||
@click="goDetail"
|
||||
v-for="(item, index) in recordList"
|
||||
:key="index"
|
||||
class="bg-white rounded-2 p-3 mb-2"
|
||||
>
|
||||
<view class="flex flex-row flex-justify-between items-center">
|
||||
<view class="flex flex-col">
|
||||
<view>{{ item.dec }}</view>
|
||||
<view class="color-gray mt-1.5">{{ item.time }}</view>
|
||||
</view>
|
||||
<view class="flex flex-row items-center">
|
||||
<view class="color-[#3372FA]">{{ item.status }}</view>
|
||||
<view class="i-carbon-chevron-right ml-2 text-2.5"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="hpx bg-gray-100 my-3"></view>
|
||||
<view class="flex flex-row flex-justify-around">
|
||||
<view class="flex flex-col items-center">
|
||||
<view class="font-bold text-5">{{ item.success }}</view>
|
||||
<view class="text-3">成功</view>
|
||||
</view>
|
||||
<view class="flex flex-col items-center">
|
||||
<view class="font-bold text-5">{{ item.fail }}</view>
|
||||
<view class="text-3">失败</view>
|
||||
</view>
|
||||
<view class="flex flex-col items-center">
|
||||
<view class="font-bold text-5">{{ item.total }}</view>
|
||||
<view class="text-3">总数</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view
|
||||
class="flex flex-row flex-justify-between px-4 py-3 box-border border-solid border-0 border-t-1 border-gray-200"
|
||||
>
|
||||
<view class="flex-1 mr-2">
|
||||
<wd-button custom-style="background:#E9EBEF;color:#3372FA" :round="false" block>
|
||||
刷新纪录
|
||||
</wd-button>
|
||||
</view>
|
||||
<view class="flex-1 ml-2">
|
||||
<wd-button :round="false" block>手动下发</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const recordList = ref([
|
||||
{
|
||||
time: '2025-01-07 10:19:28',
|
||||
dec: '系统自动操作下发',
|
||||
status: '已完成',
|
||||
success: 1,
|
||||
fail: 1,
|
||||
total: 1
|
||||
},
|
||||
{
|
||||
time: '2025-01-07 10:19:28',
|
||||
dec: '系统自动操作下发',
|
||||
status: '已完成',
|
||||
success: 1,
|
||||
fail: 1,
|
||||
total: 1
|
||||
},
|
||||
{
|
||||
time: '2025-01-07 10:19:28',
|
||||
dec: '系统自动操作下发',
|
||||
status: '已完成',
|
||||
success: 1,
|
||||
fail: 1,
|
||||
total: 1
|
||||
},
|
||||
{
|
||||
time: '2025-01-07 10:19:28',
|
||||
dec: '系统自动操作下发',
|
||||
status: '已完成',
|
||||
success: 1,
|
||||
fail: 1,
|
||||
total: 1
|
||||
},
|
||||
{
|
||||
time: '2025-01-07 10:19:28',
|
||||
dec: '系统自动操作下发',
|
||||
status: '已完成',
|
||||
success: 1,
|
||||
fail: 1,
|
||||
total: 1
|
||||
},
|
||||
{
|
||||
time: '2025-01-07 10:19:28',
|
||||
dec: '系统自动操作下发',
|
||||
status: '已完成',
|
||||
success: 1,
|
||||
fail: 1,
|
||||
total: 1
|
||||
}
|
||||
])
|
||||
const goDetail = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/attendance/issue-record-detail'
|
||||
})
|
||||
}
|
||||
//
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
//
|
||||
</style>
|
||||
@ -1,7 +0,0 @@
|
||||
<template>
|
||||
<view></view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -1,10 +0,0 @@
|
||||
<template>
|
||||
<view class="mx-4 px-2 py-3 bg-white rounded-2 shadow-sm">
|
||||
<image src="/static/images/bg_no_device.webp" mode="widthFix" class="w-full pt-2"></image>
|
||||
<view class="ml-15% mt-3 w-70% text-center custom-bg-blue color-white py-2 rounded-2 text-3.5">
|
||||
添加设备
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
@ -1,20 +0,0 @@
|
||||
<template>
|
||||
<view class="mx-4 flex-items-center flex flex-justify-between">
|
||||
<view class="w-34 h-10 color-[#134347] bg-[#cef2f5] px-4 py-3 rounded-2 shadow-sm">
|
||||
<view class="flex flex-items-center text-3.5">
|
||||
<view class="font-bold">添加人员</view>
|
||||
<wd-icon color="#134347" name="swap-right" class="ml-2" size="14px"></wd-icon>
|
||||
</view>
|
||||
<view class="mt-1 text-2.5">开启协同管理</view>
|
||||
</view>
|
||||
<view class="w-34 h-10 color-[#172a5b] bg-[#d4e0ff] px-4 py-3 rounded-2 shadow-sm">
|
||||
<view class="flex flex-items-center text-3.5">
|
||||
<view class="font-bold">添加设备</view>
|
||||
<wd-icon color="#172a5b" name="swap-right" class="ml-2" size="14px"></wd-icon>
|
||||
</view>
|
||||
<view class="mt-1 text-2.5">开启智能物联</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
@ -1,27 +0,0 @@
|
||||
<template>
|
||||
<view class="mx-4 px-2 py-3 bg-white rounded-2 shadow-sm">
|
||||
<view class="flex-items-center flex">
|
||||
<image src="/static/images/icon_one_key_door.png" class="w-4 h-4" mode="aspectFill"></image>
|
||||
<view class="text-3.5 ml-2">考勤</view>
|
||||
<wd-icon name="arrow-right" size="14px" class="ml-a" color="#bfbfbf"></wd-icon>
|
||||
</view>
|
||||
<view class="mt-3 flex-items-center flex">
|
||||
<wd-circle class="ml-4" v-model="current" :clockwise="false" :size="65" :strokeWidth="15">
|
||||
<view class="text-3.5">{{ current }}%</view>
|
||||
</wd-circle>
|
||||
<view class="ml-4 text-3">
|
||||
<view class="text-3.5 font-600">今日出勤率:2/12</view>
|
||||
<view class="flex flex-items-center mt-2">
|
||||
<view>未打卡:</view>
|
||||
<view class="color-[#ea8720]">10</view>
|
||||
<view class="ml-3">迟到:</view>
|
||||
<view class="color-red">0</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const current = ref<number>(17)
|
||||
</script>
|
||||
@ -1,14 +0,0 @@
|
||||
<template>
|
||||
<view class="mx-4 bg-white px-2 py-3 flex flex-items-center text-3.5 rounded-2 shadow-sm">
|
||||
<view>
|
||||
<text class="font-bold custom-color-black">团队</text>
|
||||
<text class="font-bold color-red">公告</text>
|
||||
</view>
|
||||
<view class="ml-2 w-1 h-1 bg-black rounded-50%"></view>
|
||||
<view class="ml-2">1</view>
|
||||
<view class="ml-a">全部</view>
|
||||
<wd-icon name="arrow-right" size="14px" class="ml-2" color="#bfbfbf"></wd-icon>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
@ -1,43 +0,0 @@
|
||||
<template>
|
||||
<view class="mx-4 px-2 py-3 bg-white rounded-2 shadow-sm">
|
||||
<view class="flex-items-center flex">
|
||||
<image src="/static/images/icon_one_key_door.png" class="w-4 h-4" mode="aspectFill"></image>
|
||||
<view class="text-3.5 ml-2">一键开门</view>
|
||||
<wd-icon name="arrow-right" size="14px" class="ml-a" color="#bfbfbf"></wd-icon>
|
||||
</view>
|
||||
<view class="flex flex-wrap mt-1 flex-justify-between">
|
||||
<view
|
||||
class="pos-relative w-40 h-24.23 mt-3 rounded-2"
|
||||
v-for="(item, index) in [1, 2, 3]"
|
||||
:key="index"
|
||||
>
|
||||
<image
|
||||
src="/static/images/bg_one_key_door.png"
|
||||
class="pos-absolute w-40 h-24.2 rounded-2"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view
|
||||
class="bg-[rgba(255,255,255,0.5)] mt-3 pos-absolute right-3 w-5 h-5 rounded-2 flex-justify-center flex flex-items-center"
|
||||
>
|
||||
<wd-icon name="play" size="22px" color="#515057"></wd-icon>
|
||||
</view>
|
||||
<view class="pos-relative ml-3 mt-3">
|
||||
<view
|
||||
class="rounded-50% w-10 h-10 flex flex-items-center flex-justify-center bg-[rgba(0,0,0,0.3)]"
|
||||
>
|
||||
<image
|
||||
src="/static/images/icon_one_key_door_key.png"
|
||||
class="w-3.5"
|
||||
mode="widthFix"
|
||||
></image>
|
||||
</view>
|
||||
<view class="mt-3 color-white font-bold text-4 w-35 truncate">
|
||||
{{ item }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user