Merge remote-tracking branch 'origin/main' into main
commit
576a9fa5e6
@ -1,144 +0,0 @@
|
|||||||
{
|
|
||||||
"typescript.tsdk": "node_modules/typescript/lib",
|
|
||||||
"npm.packageManager": "pnpm",
|
|
||||||
"editor.tabSize": 2,
|
|
||||||
"prettier.printWidth": 100, // 超过最大值换行
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
||||||
"files.eol": "\n",
|
|
||||||
"search.exclude": {
|
|
||||||
"**/node_modules": true,
|
|
||||||
"**/*.log": true,
|
|
||||||
"**/*.log*": true,
|
|
||||||
"**/bower_components": true,
|
|
||||||
"**/dist": true,
|
|
||||||
"**/elehukouben": true,
|
|
||||||
"**/.git": true,
|
|
||||||
"**/.gitignore": true,
|
|
||||||
"**/.svn": true,
|
|
||||||
"**/.DS_Store": true,
|
|
||||||
"**/.idea": true,
|
|
||||||
"**/.vscode": false,
|
|
||||||
"**/yarn.lock": true,
|
|
||||||
"**/tmp": true,
|
|
||||||
"out": true,
|
|
||||||
"dist": true,
|
|
||||||
"node_modules": true,
|
|
||||||
"CHANGELOG.md": true,
|
|
||||||
"examples": true,
|
|
||||||
"res": true,
|
|
||||||
"screenshots": true,
|
|
||||||
"yarn-error.log": true,
|
|
||||||
"**/.yarn": true
|
|
||||||
},
|
|
||||||
"files.exclude": {
|
|
||||||
"**/.cache": true,
|
|
||||||
"**/.editorconfig": true,
|
|
||||||
"**/.eslintcache": true,
|
|
||||||
"**/bower_components": true,
|
|
||||||
"**/.idea": true,
|
|
||||||
"**/tmp": true,
|
|
||||||
"**/.git": true,
|
|
||||||
"**/.svn": true,
|
|
||||||
"**/.hg": true,
|
|
||||||
"**/CVS": true,
|
|
||||||
"**/.DS_Store": true
|
|
||||||
},
|
|
||||||
"files.watcherExclude": {
|
|
||||||
"**/.git/objects/**": true,
|
|
||||||
"**/.git/subtree-cache/**": true,
|
|
||||||
"**/.vscode/**": true,
|
|
||||||
"**/node_modules/**": true,
|
|
||||||
"**/tmp/**": true,
|
|
||||||
"**/bower_components/**": true,
|
|
||||||
"**/dist/**": true,
|
|
||||||
"**/yarn.lock": true
|
|
||||||
},
|
|
||||||
"stylelint.enable": true,
|
|
||||||
"stylelint.validate": ["css", "less", "postcss", "scss", "vue", "sass"],
|
|
||||||
"path-intellisense.mappings": {
|
|
||||||
"@/": "${workspaceRoot}/src"
|
|
||||||
},
|
|
||||||
"[javascriptreact]": {
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
||||||
},
|
|
||||||
"[typescript]": {
|
|
||||||
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
|
|
||||||
},
|
|
||||||
"[typescriptreact]": {
|
|
||||||
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
|
|
||||||
},
|
|
||||||
"[html]": {
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
||||||
},
|
|
||||||
"[css]": {
|
|
||||||
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
|
|
||||||
},
|
|
||||||
"[less]": {
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
||||||
},
|
|
||||||
"[scss]": {
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
||||||
},
|
|
||||||
"[markdown]": {
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
||||||
},
|
|
||||||
"editor.codeActionsOnSave": {
|
|
||||||
"source.fixAll.eslint": "explicit"
|
|
||||||
},
|
|
||||||
"[vue]": {
|
|
||||||
"editor.defaultFormatter": "Vue.volar"
|
|
||||||
},
|
|
||||||
"i18n-ally.localesPaths": ["src/locales"],
|
|
||||||
"i18n-ally.keystyle": "nested",
|
|
||||||
"i18n-ally.sortKeys": true,
|
|
||||||
"i18n-ally.namespace": false,
|
|
||||||
"i18n-ally.enabledParsers": ["ts"],
|
|
||||||
"i18n-ally.sourceLanguage": "en",
|
|
||||||
"i18n-ally.displayLanguage": "zh-CN",
|
|
||||||
"i18n-ally.enabledFrameworks": ["vue", "react"],
|
|
||||||
"cSpell.words": [
|
|
||||||
"brotli",
|
|
||||||
"browserslist",
|
|
||||||
"codemirror",
|
|
||||||
"commitlint",
|
|
||||||
"cropperjs",
|
|
||||||
"echart",
|
|
||||||
"echarts",
|
|
||||||
"esnext",
|
|
||||||
"esno",
|
|
||||||
"iconify",
|
|
||||||
"INTLIFY",
|
|
||||||
"lintstagedrc",
|
|
||||||
"logicflow",
|
|
||||||
"nprogress",
|
|
||||||
"pinia",
|
|
||||||
"pnpm",
|
|
||||||
"qrcode",
|
|
||||||
"sider",
|
|
||||||
"sortablejs",
|
|
||||||
"stylelint",
|
|
||||||
"svgs",
|
|
||||||
"unocss",
|
|
||||||
"unplugin",
|
|
||||||
"unref",
|
|
||||||
"videojs",
|
|
||||||
"VITE",
|
|
||||||
"vitejs",
|
|
||||||
"vueuse",
|
|
||||||
"wangeditor",
|
|
||||||
"xingyu",
|
|
||||||
"yudao",
|
|
||||||
"zxcvbn"
|
|
||||||
],
|
|
||||||
// 控制相关文件嵌套展示
|
|
||||||
"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.*",
|
|
||||||
"package.json": "pnpm-lock.yaml,yarn.lock,LICENSE,README*,CHANGELOG*,CNAME,.gitattributes,.eslintrc-auto-import.json,.gitignore,prettier.config.js,stylelint.config.js,commitlint.config.js,.stylelintignore,.prettierignore,.gitpod.yml,.eslintrc.js,.eslintignore"
|
|
||||||
},
|
|
||||||
"terminal.integrated.scrollback": 10000,
|
|
||||||
"nuxt.isNuxtApp": false
|
|
||||||
}
|
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
export interface WarehouseAreaVO {
|
||||||
|
id: number
|
||||||
|
warehouseId: number
|
||||||
|
areaCode: string
|
||||||
|
areaName: string
|
||||||
|
areaSize: number
|
||||||
|
description: string
|
||||||
|
status: number
|
||||||
|
createTime: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const WarehouseAreaApi = {
|
||||||
|
getWarehouseAreaPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/erp/warehouse-area/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
getWarehouseArea: async (id: number) => {
|
||||||
|
return await request.get({ url: `/erp/warehouse-area/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
createWarehouseArea: async (data: WarehouseAreaVO) => {
|
||||||
|
return await request.post({ url: `/erp/warehouse-area/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
updateWarehouseArea: async (data: WarehouseAreaVO) => {
|
||||||
|
return await request.put({ url: `/erp/warehouse-area/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteWarehouseArea: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/erp/warehouse-area/delete?id=` + id })
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
export interface WarehouseLocationVO {
|
||||||
|
id: number
|
||||||
|
warehouseId: number
|
||||||
|
areaId: number
|
||||||
|
code: string
|
||||||
|
name: string
|
||||||
|
areaSize: number
|
||||||
|
maxLoadWeight: number
|
||||||
|
positionX: number
|
||||||
|
positionY: number
|
||||||
|
positionZ: number
|
||||||
|
allowProductMix: boolean
|
||||||
|
allowBatchMix: boolean
|
||||||
|
status: number
|
||||||
|
createTime: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const WarehouseLocationApi = {
|
||||||
|
getWarehouseLocationPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/erp/warehouse-location/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
getWarehouseLocation: async (id: number) => {
|
||||||
|
return await request.get({ url: `/erp/warehouse-location/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
createWarehouseLocation: async (data: WarehouseLocationVO) => {
|
||||||
|
return await request.post({ url: `/erp/warehouse-location/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
updateWarehouseLocation: async (data: WarehouseLocationVO) => {
|
||||||
|
return await request.put({ url: `/erp/warehouse-location/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteWarehouseLocation: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/erp/warehouse-location/delete?id=` + id })
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
export interface DeviceOperationOverviewParams {
|
||||||
|
ids?: string
|
||||||
|
startTime?: string
|
||||||
|
endTime?: string
|
||||||
|
timelinePageNo?: number
|
||||||
|
timelinePageSize?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeviceOperationOverviewMetricVO {
|
||||||
|
key: string
|
||||||
|
icon: string
|
||||||
|
value: number
|
||||||
|
unit: string
|
||||||
|
change: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeviceOperationOverviewHourlyStatusVO {
|
||||||
|
hour: string
|
||||||
|
running: number
|
||||||
|
standby: number
|
||||||
|
fault: number
|
||||||
|
offline: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeviceOperationOverviewSummaryVO {
|
||||||
|
status: 'running' | 'standby' | 'fault' | 'offline'
|
||||||
|
percent: number
|
||||||
|
hours: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeviceOperationOverviewTimelineSegmentVO {
|
||||||
|
status: 'running' | 'standby' | 'fault' | 'offline'
|
||||||
|
startHour: number
|
||||||
|
endHour: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeviceOperationOverviewTimelineRowVO {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
utilizationRate: number
|
||||||
|
segments: DeviceOperationOverviewTimelineSegmentVO[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeviceOperationOverviewRespVO {
|
||||||
|
metrics: DeviceOperationOverviewMetricVO[]
|
||||||
|
hourlyStatus: DeviceOperationOverviewHourlyStatusVO[]
|
||||||
|
summary: DeviceOperationOverviewSummaryVO[]
|
||||||
|
summaryTotalHours: number
|
||||||
|
timelineRows: DeviceOperationOverviewTimelineRowVO[]
|
||||||
|
totalDevices: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DeviceOperationOverviewApi = {
|
||||||
|
getRunOverview: async (params: DeviceOperationOverviewParams) => {
|
||||||
|
return await request.get<DeviceOperationOverviewRespVO>({
|
||||||
|
url: `/iot/device-operation-record/runOverview`,
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// 节假日设置 VO
|
||||||
|
export interface CalHolidayVO {
|
||||||
|
holidayId: number // 流水号
|
||||||
|
theDay: Date // 日期
|
||||||
|
holidayType: string // 日期类型
|
||||||
|
startTime: Date // 开始时间
|
||||||
|
endTime: Date // 结束时间
|
||||||
|
remark: string // 备注
|
||||||
|
attr1: string // 预留字段1
|
||||||
|
attr2: string // 预留字段2
|
||||||
|
attr3: number // 预留字段3
|
||||||
|
attr4: number // 预留字段4
|
||||||
|
createBy: string // 创建者
|
||||||
|
updateBy: string // 更新者
|
||||||
|
}
|
||||||
|
|
||||||
|
// 节假日设置 API
|
||||||
|
export const CalHolidayApi = {
|
||||||
|
// 查询节假日设置分页
|
||||||
|
getCalHolidayPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/mes/cal-holiday/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询节假日设置详情
|
||||||
|
getCalHoliday: async (id: number) => {
|
||||||
|
return await request.get({ url: `/mes/cal-holiday/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增节假日设置
|
||||||
|
createCalHoliday: async (data: CalHolidayVO) => {
|
||||||
|
return await request.post({ url: `/mes/cal-holiday/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改节假日设置
|
||||||
|
updateCalHoliday: async (data: CalHolidayVO) => {
|
||||||
|
return await request.put({ url: `/mes/cal-holiday/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除节假日设置
|
||||||
|
deleteCalHoliday: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/mes/cal-holiday/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出节假日设置 Excel
|
||||||
|
exportCalHoliday: async (params) => {
|
||||||
|
return await request.download({ url: `/mes/cal-holiday/export-excel`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除节假日设置
|
||||||
|
deleteCalHolidayByDay: async (theDay: String) => {
|
||||||
|
return await request.delete({ url: `/mes/cal-holiday/deleteByDay?theDay=` + theDay })
|
||||||
|
},
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
export interface CapacityReportVO {
|
||||||
|
id: number
|
||||||
|
deviceCode: string
|
||||||
|
deviceName: string
|
||||||
|
typeName: string
|
||||||
|
deviceStatus: number
|
||||||
|
ratedCapacity: number
|
||||||
|
reportCapacity: number
|
||||||
|
actualCapacity: number
|
||||||
|
workshopName: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CapacityReportQuery {
|
||||||
|
pageNo: number
|
||||||
|
pageSize: number
|
||||||
|
deviceCode?: string
|
||||||
|
deviceName?: string
|
||||||
|
deviceType?: string
|
||||||
|
deviceStatus?: string
|
||||||
|
workshop?: string
|
||||||
|
ids?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DeviceLedgerApi = {
|
||||||
|
/**
|
||||||
|
* 产能报表分页查询
|
||||||
|
*/
|
||||||
|
getCapacityReportPage: async (params: CapacityReportQuery) => {
|
||||||
|
return await request.get({ url: '/mes/device-ledger/capacity-report/page', params })
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 产能报表导出
|
||||||
|
*/
|
||||||
|
exportCapacityReport: async (params: { ids?: string }) => {
|
||||||
|
return await request.download({ url: '/mes/device-ledger/capacity-report/export-excel', params })
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新设备状态
|
||||||
|
*/
|
||||||
|
updateDeviceLedger: async (data: { id: number; deviceStatus: number }) => {
|
||||||
|
return await request.put({ url: '/mes/device-ledger/update', data })
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
export interface DeviceLineVO {
|
||||||
|
id: number
|
||||||
|
code: string
|
||||||
|
isCode?: boolean
|
||||||
|
qrcodeUrl?: string
|
||||||
|
name: string
|
||||||
|
remark: string
|
||||||
|
sort: number
|
||||||
|
parentId: number
|
||||||
|
parentChain: string
|
||||||
|
createTime?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeviceLineTreeVO extends DeviceLineVO {
|
||||||
|
children?: DeviceLineTreeVO[]
|
||||||
|
leaf?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DeviceLineApi = {
|
||||||
|
getDeviceLine: async (id: number) => {
|
||||||
|
return await request.get({ url: `/mes/device-line/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
getDeviceLineTree: async () => {
|
||||||
|
return await request.get({ url: `/mes/device-line/tree` })
|
||||||
|
},
|
||||||
|
|
||||||
|
regenerateCode: async (id: number, code: string) => {
|
||||||
|
return await request.post({ url: `/mes/device-line/regenerate-code?id=${id}&code=${encodeURIComponent(code)}` })
|
||||||
|
},
|
||||||
|
|
||||||
|
createDeviceLine: async (data: DeviceLineVO) => {
|
||||||
|
return await request.post({ url: `/mes/device-line/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
updateDeviceLine: async (data: DeviceLineVO) => {
|
||||||
|
return await request.put({ url: `/mes/device-line/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteDeviceLine: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/mes/device-line/delete?id=` + id })
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// esop文件表库 VO
|
||||||
|
export interface FileVO {
|
||||||
|
id: number // id
|
||||||
|
configId: number // 配置编号
|
||||||
|
code: string // 文件编码
|
||||||
|
name: string // 文件名
|
||||||
|
path: string // 文件路径
|
||||||
|
url: string // 文件 URL
|
||||||
|
type: string // 文件类型
|
||||||
|
class: string // 文件分类
|
||||||
|
status: number // 文件状态
|
||||||
|
size: number // 文件大小
|
||||||
|
}
|
||||||
|
// 文件预签名地址 Response VO
|
||||||
|
export interface FilePresignedUrlRespVO {
|
||||||
|
// 文件配置编号
|
||||||
|
configId: number
|
||||||
|
// 文件上传 URL
|
||||||
|
uploadUrl: string
|
||||||
|
// 文件 URL
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ApiUrl{
|
||||||
|
'/admin-api/mes/esop/file/create'
|
||||||
|
}
|
||||||
|
|
||||||
|
// esop文件表库 API
|
||||||
|
export const FileApi = {
|
||||||
|
// 查询esop文件表库分页
|
||||||
|
getFilePage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/esop/file/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// 查询esop文件表库详情
|
||||||
|
getFile: async (id: number) => {
|
||||||
|
return await request.get({ url: `/esop/file/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增esop文件表库
|
||||||
|
createFile: async (data: FileVO) => {
|
||||||
|
return await request.post({ url: `/esop/file/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改esop文件表库
|
||||||
|
updateFile: async (data: FileVO) => {
|
||||||
|
return await request.put({ url: `/esop/file/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除esop文件表库
|
||||||
|
deleteFile: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/esop/file/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出esop文件表库 Excel
|
||||||
|
exportFile: async (params) => {
|
||||||
|
return await request.download({ url: `/esop/file/export-excel`, params })
|
||||||
|
},
|
||||||
|
// 获取文件编码
|
||||||
|
generateCode: async () => {
|
||||||
|
return await request.get({ url: `/esop/file/generate`})
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取文件预签名地址
|
||||||
|
export const getFilePresignedUrl = (path: string) => {
|
||||||
|
return request.get<FilePresignedUrlRespVO>({
|
||||||
|
url: '/infra/file/presigned-url',
|
||||||
|
params: { path }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建文件
|
||||||
|
export const createFile = (data: any) => {
|
||||||
|
return request.post({ url: '/esop/file/create', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传文件
|
||||||
|
export const updateFile = (data: any) => {
|
||||||
|
return request.upload({ url: '/esop/file/create', data })
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
export interface PrintTemplateVO {
|
||||||
|
id: number
|
||||||
|
templateCode: string
|
||||||
|
templateName: string
|
||||||
|
templateType: number
|
||||||
|
templateBizType: number
|
||||||
|
templateJson: string
|
||||||
|
remark: string
|
||||||
|
isEnable: boolean
|
||||||
|
createTime: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PrintTemplateApi = {
|
||||||
|
getPrintTemplatePage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/mes/print-template/page`, params })
|
||||||
|
},
|
||||||
|
getPrintTemplate: async (id: number) => {
|
||||||
|
return await request.get({ url: `/mes/print-template/get?id=` + id })
|
||||||
|
},
|
||||||
|
createPrintTemplate: async (data: PrintTemplateVO) => {
|
||||||
|
return await request.post({ url: `/mes/print-template/create`, data })
|
||||||
|
},
|
||||||
|
updatePrintTemplate: async (data: PrintTemplateVO) => {
|
||||||
|
return await request.put({ url: `/mes/print-template/update`, data })
|
||||||
|
},
|
||||||
|
deletePrintTemplate: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/mes/print-template/delete?id=` + id })
|
||||||
|
},
|
||||||
|
exportPrintTemplate: async (params) => {
|
||||||
|
return await request.download({ url: `/mes/print-template/export-excel`, params })
|
||||||
|
},
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 366 B |
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
@ -1,4 +1,5 @@
|
|||||||
import Icon from './src/Icon.vue'
|
import Icon from './src/Icon.vue'
|
||||||
import IconSelect from './src/IconSelect.vue'
|
import IconSelect from './src/IconSelect.vue'
|
||||||
|
import AppIconSelect from './src/AppIconSelect.vue'
|
||||||
|
|
||||||
export { Icon, IconSelect }
|
export { Icon, IconSelect, AppIconSelect }
|
||||||
|
|||||||
@ -0,0 +1,280 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { uniIconsList, uviewIconsList, uniIconsUnicodeMap, uviewIconsUnicodeMap } from './appIconData'
|
||||||
|
|
||||||
|
defineOptions({ name: 'AppIconSelect' })
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
require: false,
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
clearable: {
|
||||||
|
require: false,
|
||||||
|
type: Boolean
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const emit = defineEmits<{ (e: 'update:modelValue', v: string) }>()
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
const inputValue = toRef(props, 'modelValue')
|
||||||
|
const currentActiveType = ref('uni-icons')
|
||||||
|
const filterValue = ref('')
|
||||||
|
|
||||||
|
const iconDataMap: Record<string, string[]> = {
|
||||||
|
'uni-icons': uniIconsList,
|
||||||
|
'uview-plus': uviewIconsList
|
||||||
|
}
|
||||||
|
|
||||||
|
const unicodeMapMap: Record<string, Record<string, string>> = {
|
||||||
|
'uni-icons': uniIconsUnicodeMap,
|
||||||
|
'uview-plus': uviewIconsUnicodeMap
|
||||||
|
}
|
||||||
|
|
||||||
|
const fontFamilyMap: Record<string, string> = {
|
||||||
|
'uni-icons': 'UniIconsFontFamily',
|
||||||
|
'uview-plus': 'uview-iconfont'
|
||||||
|
}
|
||||||
|
|
||||||
|
const tabsList = [
|
||||||
|
{ label: 'uni-icons', name: 'uni-icons' },
|
||||||
|
{ label: 'uview-plus', name: 'uview-plus' }
|
||||||
|
]
|
||||||
|
|
||||||
|
const pageSize = ref(96)
|
||||||
|
const currentPage = ref(1)
|
||||||
|
|
||||||
|
const currentIconList = computed(() => {
|
||||||
|
return iconDataMap[currentActiveType.value] || []
|
||||||
|
})
|
||||||
|
|
||||||
|
const currentUnicodeMap = computed(() => {
|
||||||
|
return unicodeMapMap[currentActiveType.value] || {}
|
||||||
|
})
|
||||||
|
|
||||||
|
const currentFontFamily = computed(() => {
|
||||||
|
return fontFamilyMap[currentActiveType.value] || 'UniIconsFontFamily'
|
||||||
|
})
|
||||||
|
|
||||||
|
const filteredList = computed(() => {
|
||||||
|
return currentIconList.value.filter((v) =>
|
||||||
|
v.toLowerCase().includes(filterValue.value.toLowerCase())
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const pageList = computed(() => {
|
||||||
|
if (currentPage.value === 1) {
|
||||||
|
return filteredList.value.slice(0, pageSize.value)
|
||||||
|
}
|
||||||
|
return filteredList.value.slice(
|
||||||
|
pageSize.value * (currentPage.value - 1),
|
||||||
|
pageSize.value * (currentPage.value - 1) + pageSize.value
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const iconCount = computed(() => filteredList.value.length)
|
||||||
|
|
||||||
|
function parseIconValue(value: string): { prefix: string; name: string } | null {
|
||||||
|
if (!value || value.indexOf(':') < 0) return null
|
||||||
|
const idx = value.indexOf(':')
|
||||||
|
return {
|
||||||
|
prefix: value.substring(0, idx),
|
||||||
|
name: value.substring(idx + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUnicode(name: string): string {
|
||||||
|
return currentUnicodeMap.value[name] || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectedFontFamily(fullValue: string): string {
|
||||||
|
const parsed = parseIconValue(fullValue)
|
||||||
|
if (!parsed) return 'UniIconsFontFamily'
|
||||||
|
return fontFamilyMap[parsed.prefix] || 'UniIconsFontFamily'
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectedUnicode(fullValue: string): string {
|
||||||
|
const parsed = parseIconValue(fullValue)
|
||||||
|
if (!parsed) return ''
|
||||||
|
const map = unicodeMapMap[parsed.prefix]
|
||||||
|
return map ? map[parsed.name] || '' : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleClick({ props }: any) {
|
||||||
|
currentPage.value = 1
|
||||||
|
currentActiveType.value = props.name
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChangeIcon(item: string) {
|
||||||
|
emit('update:modelValue', currentActiveType.value + ':' + item)
|
||||||
|
visible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCurrentChange(page: number) {
|
||||||
|
currentPage.value = page
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearIcon() {
|
||||||
|
emit('update:modelValue', '')
|
||||||
|
visible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(val) => {
|
||||||
|
if (val) {
|
||||||
|
const parsed = parseIconValue(val)
|
||||||
|
if (parsed && fontFamilyMap[parsed.prefix]) {
|
||||||
|
currentActiveType.value = parsed.prefix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => filterValue.value,
|
||||||
|
() => {
|
||||||
|
currentPage.value = 1
|
||||||
|
}
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="selector">
|
||||||
|
<ElInput v-model="inputValue" @click="visible = !visible" :clearable="props.clearable" @clear="clearIcon">
|
||||||
|
<template #append>
|
||||||
|
<ElPopover
|
||||||
|
:visible="visible"
|
||||||
|
:width="355"
|
||||||
|
popper-class="pure-popper"
|
||||||
|
trigger="click"
|
||||||
|
>
|
||||||
|
<template #reference>
|
||||||
|
<div
|
||||||
|
class="h-32px w-40px flex cursor-pointer items-center justify-center"
|
||||||
|
@click="visible = !visible"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
v-if="inputValue && getSelectedUnicode(inputValue)"
|
||||||
|
class="app-icon-font"
|
||||||
|
:style="{ fontFamily: getSelectedFontFamily(inputValue), fontSize: '18px' }"
|
||||||
|
>{{ getSelectedUnicode(inputValue) }}</span>
|
||||||
|
<span v-else class="text-12px color-gray-500">选择</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<ElInput v-model="filterValue" class="p-2" clearable placeholder="搜索图标" />
|
||||||
|
<ElDivider border-style="dashed" />
|
||||||
|
|
||||||
|
<ElTabs v-model="currentActiveType" @tab-click="handleClick">
|
||||||
|
<ElTabPane
|
||||||
|
v-for="(pane, index) in tabsList"
|
||||||
|
:key="index"
|
||||||
|
:label="pane.label"
|
||||||
|
:name="pane.name"
|
||||||
|
>
|
||||||
|
<ElDivider border-style="dashed" class="tab-divider" />
|
||||||
|
<ElScrollbar height="220px">
|
||||||
|
<ul class="ml-2 flex flex-wrap">
|
||||||
|
<li
|
||||||
|
v-for="(item, key) in pageList"
|
||||||
|
:key="key"
|
||||||
|
:style="inputValue === currentActiveType + ':' + item ? { borderColor: 'var(--el-color-primary)', color: 'var(--el-color-primary)' } : {}"
|
||||||
|
:title="item"
|
||||||
|
class="icon-item mr-2 mt-1 w-1/10 flex cursor-pointer items-center justify-center border border-solid p-2"
|
||||||
|
@click="onChangeIcon(item)"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="app-icon-font"
|
||||||
|
:style="{ fontFamily: currentFontFamily }"
|
||||||
|
>{{ getUnicode(item) }}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</ElScrollbar>
|
||||||
|
</ElTabPane>
|
||||||
|
</ElTabs>
|
||||||
|
<ElDivider border-style="dashed" />
|
||||||
|
|
||||||
|
<ElPagination
|
||||||
|
:current-page="currentPage"
|
||||||
|
:page-size="pageSize"
|
||||||
|
:total="iconCount"
|
||||||
|
background
|
||||||
|
class="h-10 flex items-center justify-center"
|
||||||
|
layout="prev, pager, next"
|
||||||
|
size="small"
|
||||||
|
@current-change="onCurrentChange"
|
||||||
|
/>
|
||||||
|
</ElPopover>
|
||||||
|
</template>
|
||||||
|
</ElInput>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@font-face {
|
||||||
|
font-family: 'UniIconsFontFamily';
|
||||||
|
src: url('@/assets/fonts/uniicons.ttf') format('truetype');
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'uview-iconfont';
|
||||||
|
src: url('@/assets/fonts/uview-icons.ttf') format('truetype');
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.app-icon-font {
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 20px;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-divider--horizontal {
|
||||||
|
margin: 1px auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-divider.el-divider--horizontal {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-item {
|
||||||
|
&:hover {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
border-color: var(--el-color-primary);
|
||||||
|
transform: scaleX(1.05);
|
||||||
|
transition: all 0.4s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tabs__nav-next) {
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 32px;
|
||||||
|
box-shadow: -5px 0 5px -6px #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tabs__nav-prev) {
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 32px;
|
||||||
|
box-shadow: 5px 0 5px -6px #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-input-group__append) {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tabs__item) {
|
||||||
|
height: 30px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tabs__header),
|
||||||
|
:deep(.el-tabs__nav-wrap) {
|
||||||
|
position: static;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,382 @@
|
|||||||
|
const uniIconsUnicodeMap: Record<string, string> = {
|
||||||
|
'arrow-down': '\ue6be',
|
||||||
|
'arrow-left': '\ue6bc',
|
||||||
|
'arrow-right': '\ue6bb',
|
||||||
|
'arrow-up': '\ue6bd',
|
||||||
|
'auth': '\ue6ab',
|
||||||
|
'auth-filled': '\ue6cc',
|
||||||
|
'back': '\ue6b9',
|
||||||
|
'bars': '\ue627',
|
||||||
|
'calendar': '\ue6a0',
|
||||||
|
'calendar-filled': '\ue6c0',
|
||||||
|
'camera': '\ue65a',
|
||||||
|
'camera-filled': '\ue658',
|
||||||
|
'cart': '\ue631',
|
||||||
|
'cart-filled': '\ue6d0',
|
||||||
|
'chat': '\ue65d',
|
||||||
|
'chat-filled': '\ue659',
|
||||||
|
'chatboxes': '\ue696',
|
||||||
|
'chatboxes-filled': '\ue692',
|
||||||
|
'chatbubble': '\ue697',
|
||||||
|
'chatbubble-filled': '\ue694',
|
||||||
|
'checkbox': '\ue62b',
|
||||||
|
'checkbox-filled': '\ue62c',
|
||||||
|
'checkmarkempty': '\ue65c',
|
||||||
|
'circle': '\ue65b',
|
||||||
|
'circle-filled': '\ue65e',
|
||||||
|
'clear': '\ue66d',
|
||||||
|
'close': '\ue673',
|
||||||
|
'closeempty': '\ue66c',
|
||||||
|
'cloud-download': '\ue647',
|
||||||
|
'cloud-download-filled': '\ue646',
|
||||||
|
'cloud-upload': '\ue645',
|
||||||
|
'cloud-upload-filled': '\ue648',
|
||||||
|
'color': '\ue6cf',
|
||||||
|
'color-filled': '\ue6c9',
|
||||||
|
'compose': '\ue67f',
|
||||||
|
'contact': '\ue693',
|
||||||
|
'contact-filled': '\ue695',
|
||||||
|
'down': '\ue6b8',
|
||||||
|
'bottom': '\ue6b8',
|
||||||
|
'download': '\ue68d',
|
||||||
|
'download-filled': '\ue681',
|
||||||
|
'email': '\ue69e',
|
||||||
|
'email-filled': '\ue69a',
|
||||||
|
'eye': '\ue651',
|
||||||
|
'eye-filled': '\ue66a',
|
||||||
|
'eye-slash': '\ue6b3',
|
||||||
|
'eye-slash-filled': '\ue6b4',
|
||||||
|
'fire': '\ue6a1',
|
||||||
|
'fire-filled': '\ue6c5',
|
||||||
|
'flag': '\ue65f',
|
||||||
|
'flag-filled': '\ue660',
|
||||||
|
'folder-add': '\ue6a9',
|
||||||
|
'folder-add-filled': '\ue6c8',
|
||||||
|
'font': '\ue6a3',
|
||||||
|
'forward': '\ue6ba',
|
||||||
|
'gear': '\ue664',
|
||||||
|
'gear-filled': '\ue661',
|
||||||
|
'gift': '\ue6a4',
|
||||||
|
'gift-filled': '\ue6c4',
|
||||||
|
'hand-down': '\ue63d',
|
||||||
|
'hand-down-filled': '\ue63c',
|
||||||
|
'hand-up': '\ue63f',
|
||||||
|
'hand-up-filled': '\ue63e',
|
||||||
|
'headphones': '\ue630',
|
||||||
|
'heart': '\ue639',
|
||||||
|
'heart-filled': '\ue641',
|
||||||
|
'help': '\ue679',
|
||||||
|
'help-filled': '\ue674',
|
||||||
|
'home': '\ue662',
|
||||||
|
'home-filled': '\ue663',
|
||||||
|
'image': '\ue670',
|
||||||
|
'image-filled': '\ue678',
|
||||||
|
'images': '\ue650',
|
||||||
|
'images-filled': '\ue64b',
|
||||||
|
'info': '\ue669',
|
||||||
|
'info-filled': '\ue649',
|
||||||
|
'left': '\ue6b7',
|
||||||
|
'link': '\ue6a5',
|
||||||
|
'list': '\ue644',
|
||||||
|
'location': '\ue6ae',
|
||||||
|
'location-filled': '\ue6af',
|
||||||
|
'locked': '\ue66b',
|
||||||
|
'locked-filled': '\ue668',
|
||||||
|
'loop': '\ue633',
|
||||||
|
'mail-open': '\ue643',
|
||||||
|
'mail-open-filled': '\ue63a',
|
||||||
|
'map': '\ue667',
|
||||||
|
'map-filled': '\ue666',
|
||||||
|
'map-pin': '\ue6ad',
|
||||||
|
'map-pin-ellipse': '\ue6ac',
|
||||||
|
'medal': '\ue6a2',
|
||||||
|
'medal-filled': '\ue6c3',
|
||||||
|
'mic': '\ue671',
|
||||||
|
'mic-filled': '\ue677',
|
||||||
|
'micoff': '\ue67e',
|
||||||
|
'micoff-filled': '\ue6b0',
|
||||||
|
'minus': '\ue66f',
|
||||||
|
'minus-filled': '\ue67d',
|
||||||
|
'more': '\ue64d',
|
||||||
|
'more-filled': '\ue64e',
|
||||||
|
'navigate': '\ue66e',
|
||||||
|
'navigate-filled': '\ue67a',
|
||||||
|
'notification': '\ue6a6',
|
||||||
|
'notification-filled': '\ue6c1',
|
||||||
|
'paperclip': '\ue652',
|
||||||
|
'paperplane': '\ue672',
|
||||||
|
'paperplane-filled': '\ue675',
|
||||||
|
'person': '\ue699',
|
||||||
|
'person-filled': '\ue69d',
|
||||||
|
'personadd': '\ue69f',
|
||||||
|
'personadd-filled': '\ue698',
|
||||||
|
'phone': '\ue69c',
|
||||||
|
'phone-filled': '\ue69b',
|
||||||
|
'plus': '\ue676',
|
||||||
|
'plus-filled': '\ue6c7',
|
||||||
|
'plusempty': '\ue67b',
|
||||||
|
'pulldown': '\ue632',
|
||||||
|
'pyq': '\ue682',
|
||||||
|
'qq': '\ue680',
|
||||||
|
'redo': '\ue64a',
|
||||||
|
'redo-filled': '\ue655',
|
||||||
|
'refresh': '\ue657',
|
||||||
|
'refresh-filled': '\ue656',
|
||||||
|
'refreshempty': '\ue6bf',
|
||||||
|
'reload': '\ue6b2',
|
||||||
|
'right': '\ue6b5',
|
||||||
|
'scan': '\ue62a',
|
||||||
|
'search': '\ue654',
|
||||||
|
'settings': '\ue653',
|
||||||
|
'settings-filled': '\ue6ce',
|
||||||
|
'shop': '\ue62f',
|
||||||
|
'shop-filled': '\ue6cd',
|
||||||
|
'smallcircle': '\ue67c',
|
||||||
|
'smallcircle-filled': '\ue665',
|
||||||
|
'sound': '\ue684',
|
||||||
|
'sound-filled': '\ue686',
|
||||||
|
'spinner-cycle': '\ue68a',
|
||||||
|
'staff': '\ue6a7',
|
||||||
|
'staff-filled': '\ue6cb',
|
||||||
|
'star': '\ue688',
|
||||||
|
'star-filled': '\ue68f',
|
||||||
|
'starhalf': '\ue683',
|
||||||
|
'trash': '\ue687',
|
||||||
|
'trash-filled': '\ue685',
|
||||||
|
'tune': '\ue6aa',
|
||||||
|
'tune-filled': '\ue6ca',
|
||||||
|
'undo': '\ue64f',
|
||||||
|
'undo-filled': '\ue64c',
|
||||||
|
'up': '\ue6b6',
|
||||||
|
'top': '\ue6b6',
|
||||||
|
'upload': '\ue690',
|
||||||
|
'upload-filled': '\ue68e',
|
||||||
|
'videocam': '\ue68c',
|
||||||
|
'videocam-filled': '\ue689',
|
||||||
|
'vip': '\ue6a8',
|
||||||
|
'vip-filled': '\ue6c6',
|
||||||
|
'wallet': '\ue6b1',
|
||||||
|
'wallet-filled': '\ue6c2',
|
||||||
|
'weibo': '\ue68b',
|
||||||
|
'weixin': '\ue691'
|
||||||
|
}
|
||||||
|
|
||||||
|
const uviewIconsUnicodeMap: Record<string, string> = {
|
||||||
|
'level': '\ue693',
|
||||||
|
'column-line': '\ue68e',
|
||||||
|
'checkbox-mark': '\ue807',
|
||||||
|
'folder': '\ue7f5',
|
||||||
|
'movie': '\ue7f6',
|
||||||
|
'star-fill': '\ue669',
|
||||||
|
'star': '\ue65f',
|
||||||
|
'phone-fill': '\ue64f',
|
||||||
|
'phone': '\ue622',
|
||||||
|
'apple-fill': '\ue881',
|
||||||
|
'chrome-circle-fill': '\ue885',
|
||||||
|
'backspace': '\ue67b',
|
||||||
|
'attach': '\ue632',
|
||||||
|
'cut': '\ue948',
|
||||||
|
'empty-car': '\ue602',
|
||||||
|
'empty-coupon': '\ue682',
|
||||||
|
'empty-address': '\ue646',
|
||||||
|
'empty-favor': '\ue67c',
|
||||||
|
'empty-permission': '\ue686',
|
||||||
|
'empty-news': '\ue687',
|
||||||
|
'empty-search': '\ue664',
|
||||||
|
'github-circle-fill': '\ue887',
|
||||||
|
'rmb': '\ue608',
|
||||||
|
'person-delete-fill': '\ue66a',
|
||||||
|
'reload': '\ue788',
|
||||||
|
'order': '\ue68f',
|
||||||
|
'server-man': '\ue6bc',
|
||||||
|
'search': '\ue62a',
|
||||||
|
'fingerprint': '\ue955',
|
||||||
|
'more-dot-fill': '\ue630',
|
||||||
|
'scan': '\ue662',
|
||||||
|
'share-square': '\ue60b',
|
||||||
|
'map': '\ue61d',
|
||||||
|
'map-fill': '\ue64e',
|
||||||
|
'tags': '\ue629',
|
||||||
|
'tags-fill': '\ue651',
|
||||||
|
'bookmark-fill': '\ue63b',
|
||||||
|
'bookmark': '\ue60a',
|
||||||
|
'eye': '\ue613',
|
||||||
|
'eye-fill': '\ue641',
|
||||||
|
'mic': '\ue64a',
|
||||||
|
'mic-off': '\ue649',
|
||||||
|
'calendar': '\ue66e',
|
||||||
|
'calendar-fill': '\ue634',
|
||||||
|
'trash': '\ue623',
|
||||||
|
'trash-fill': '\ue658',
|
||||||
|
'play-left': '\ue66d',
|
||||||
|
'play-right': '\ue610',
|
||||||
|
'minus': '\ue618',
|
||||||
|
'plus': '\ue62d',
|
||||||
|
'info': '\ue653',
|
||||||
|
'info-circle': '\ue7d2',
|
||||||
|
'info-circle-fill': '\ue64b',
|
||||||
|
'question': '\ue715',
|
||||||
|
'error': '\ue6d3',
|
||||||
|
'close': '\ue685',
|
||||||
|
'checkmark': '\ue6a8',
|
||||||
|
'android-circle-fill': '\ue67e',
|
||||||
|
'android-fill': '\ue67d',
|
||||||
|
'ie': '\ue87b',
|
||||||
|
'IE-circle-fill': '\ue889',
|
||||||
|
'google': '\ue87a',
|
||||||
|
'google-circle-fill': '\ue88a',
|
||||||
|
'setting-fill': '\ue872',
|
||||||
|
'setting': '\ue61f',
|
||||||
|
'minus-square-fill': '\ue855',
|
||||||
|
'plus-square-fill': '\ue856',
|
||||||
|
'heart': '\ue7df',
|
||||||
|
'heart-fill': '\ue851',
|
||||||
|
'camera': '\ue7d7',
|
||||||
|
'camera-fill': '\ue870',
|
||||||
|
'more-circle': '\ue63e',
|
||||||
|
'more-circle-fill': '\ue645',
|
||||||
|
'chat': '\ue620',
|
||||||
|
'chat-fill': '\ue61e',
|
||||||
|
'bag-fill': '\ue617',
|
||||||
|
'bag': '\ue619',
|
||||||
|
'error-circle-fill': '\ue62c',
|
||||||
|
'error-circle': '\ue624',
|
||||||
|
'close-circle': '\ue63f',
|
||||||
|
'close-circle-fill': '\ue637',
|
||||||
|
'checkmark-circle': '\ue63d',
|
||||||
|
'checkmark-circle-fill': '\ue635',
|
||||||
|
'question-circle-fill': '\ue666',
|
||||||
|
'question-circle': '\ue625',
|
||||||
|
'share': '\ue631',
|
||||||
|
'share-fill': '\ue65e',
|
||||||
|
'shopping-cart': '\ue621',
|
||||||
|
'shopping-cart-fill': '\ue65d',
|
||||||
|
'bell': '\ue609',
|
||||||
|
'bell-fill': '\ue640',
|
||||||
|
'list': '\ue650',
|
||||||
|
'list-dot': '\ue616',
|
||||||
|
'zhihu': '\ue6ba',
|
||||||
|
'zhihu-circle-fill': '\ue709',
|
||||||
|
'zhifubao': '\ue6b9',
|
||||||
|
'zhifubao-circle-fill': '\ue6b8',
|
||||||
|
'weixin-circle-fill': '\ue6b1',
|
||||||
|
'weixin-fill': '\ue6b2',
|
||||||
|
'twitter-circle-fill': '\ue6ab',
|
||||||
|
'twitter': '\ue6aa',
|
||||||
|
'taobao-circle-fill': '\ue6a7',
|
||||||
|
'taobao': '\ue6a6',
|
||||||
|
'weibo-circle-fill': '\ue6a5',
|
||||||
|
'weibo': '\ue6a4',
|
||||||
|
'qq-fill': '\ue6a1',
|
||||||
|
'qq-circle-fill': '\ue6a0',
|
||||||
|
'moments-circel-fill': '\ue69a',
|
||||||
|
'moments': '\ue69b',
|
||||||
|
'qzone': '\ue695',
|
||||||
|
'qzone-circle-fill': '\ue696',
|
||||||
|
'baidu-circle-fill': '\ue680',
|
||||||
|
'baidu': '\ue681',
|
||||||
|
'facebook-circle-fill': '\ue68a',
|
||||||
|
'facebook': '\ue689',
|
||||||
|
'car': '\ue60c',
|
||||||
|
'car-fill': '\ue636',
|
||||||
|
'warning-fill': '\ue64d',
|
||||||
|
'warning': '\ue694',
|
||||||
|
'clock-fill': '\ue638',
|
||||||
|
'clock': '\ue60f',
|
||||||
|
'edit-pen': '\ue612',
|
||||||
|
'edit-pen-fill': '\ue66b',
|
||||||
|
'email': '\ue611',
|
||||||
|
'email-fill': '\ue642',
|
||||||
|
'minus-circle': '\ue61b',
|
||||||
|
'minus-circle-fill': '\ue652',
|
||||||
|
'plus-circle': '\ue62e',
|
||||||
|
'plus-circle-fill': '\ue661',
|
||||||
|
'file-text': '\ue663',
|
||||||
|
'file-text-fill': '\ue665',
|
||||||
|
'pushpin': '\ue7e3',
|
||||||
|
'pushpin-fill': '\ue86e',
|
||||||
|
'grid': '\ue673',
|
||||||
|
'grid-fill': '\ue678',
|
||||||
|
'play-circle': '\ue647',
|
||||||
|
'play-circle-fill': '\ue655',
|
||||||
|
'pause-circle-fill': '\ue654',
|
||||||
|
'pause': '\ue8fa',
|
||||||
|
'pause-circle': '\ue643',
|
||||||
|
'eye-off': '\ue648',
|
||||||
|
'eye-off-outline': '\ue62b',
|
||||||
|
'gift-fill': '\ue65c',
|
||||||
|
'gift': '\ue65b',
|
||||||
|
'rmb-circle-fill': '\ue657',
|
||||||
|
'rmb-circle': '\ue677',
|
||||||
|
'kefu-ermai': '\ue656',
|
||||||
|
'server-fill': '\ue751',
|
||||||
|
'coupon-fill': '\ue8c4',
|
||||||
|
'coupon': '\ue8ae',
|
||||||
|
'integral': '\ue704',
|
||||||
|
'integral-fill': '\ue703',
|
||||||
|
'home-fill': '\ue964',
|
||||||
|
'home': '\ue965',
|
||||||
|
'hourglass-half-fill': '\ue966',
|
||||||
|
'hourglass': '\ue967',
|
||||||
|
'account': '\ue628',
|
||||||
|
'plus-people-fill': '\ue626',
|
||||||
|
'minus-people-fill': '\ue615',
|
||||||
|
'account-fill': '\ue614',
|
||||||
|
'thumb-down-fill': '\ue726',
|
||||||
|
'thumb-down': '\ue727',
|
||||||
|
'thumb-up': '\ue733',
|
||||||
|
'thumb-up-fill': '\ue72f',
|
||||||
|
'lock-fill': '\ue979',
|
||||||
|
'lock-open': '\ue973',
|
||||||
|
'lock-opened-fill': '\ue974',
|
||||||
|
'lock': '\ue97a',
|
||||||
|
'red-packet-fill': '\ue690',
|
||||||
|
'photo-fill': '\ue98b',
|
||||||
|
'photo': '\ue98d',
|
||||||
|
'volume-off-fill': '\ue659',
|
||||||
|
'volume-off': '\ue644',
|
||||||
|
'volume-fill': '\ue670',
|
||||||
|
'volume': '\ue633',
|
||||||
|
'red-packet': '\ue691',
|
||||||
|
'download': '\ue63c',
|
||||||
|
'arrow-up-fill': '\ue6b0',
|
||||||
|
'arrow-down-fill': '\ue600',
|
||||||
|
'play-left-fill': '\ue675',
|
||||||
|
'play-right-fill': '\ue676',
|
||||||
|
'rewind-left-fill': '\ue679',
|
||||||
|
'rewind-right-fill': '\ue67a',
|
||||||
|
'arrow-downward': '\ue604',
|
||||||
|
'arrow-leftward': '\ue601',
|
||||||
|
'arrow-rightward': '\ue603',
|
||||||
|
'arrow-upward': '\ue607',
|
||||||
|
'arrow-down': '\ue60d',
|
||||||
|
'arrow-right': '\ue605',
|
||||||
|
'arrow-left': '\ue60e',
|
||||||
|
'arrow-up': '\ue606',
|
||||||
|
'skip-back-left': '\ue674',
|
||||||
|
'skip-forward-right': '\ue672',
|
||||||
|
'rewind-right': '\ue66f',
|
||||||
|
'rewind-left': '\ue671',
|
||||||
|
'arrow-right-double': '\ue68d',
|
||||||
|
'arrow-left-double': '\ue68c',
|
||||||
|
'wifi-off': '\ue668',
|
||||||
|
'wifi': '\ue667',
|
||||||
|
'empty-data': '\ue62f',
|
||||||
|
'empty-history': '\ue684',
|
||||||
|
'empty-list': '\ue68b',
|
||||||
|
'empty-page': '\ue627',
|
||||||
|
'empty-order': '\ue639',
|
||||||
|
'man': '\ue697',
|
||||||
|
'woman': '\ue69c',
|
||||||
|
'man-add': '\ue61c',
|
||||||
|
'man-add-fill': '\ue64c',
|
||||||
|
'man-delete': '\ue61a',
|
||||||
|
'man-delete-fill': '\ue66a',
|
||||||
|
'zh': '\ue70a',
|
||||||
|
'en': '\ue692'
|
||||||
|
}
|
||||||
|
|
||||||
|
const uniIconsList = Object.keys(uniIconsUnicodeMap)
|
||||||
|
const uviewIconsList = Object.keys(uviewIconsUnicodeMap)
|
||||||
|
|
||||||
|
export { uniIconsList, uviewIconsList, uniIconsUnicodeMap, uviewIconsUnicodeMap }
|
||||||
@ -0,0 +1,371 @@
|
|||||||
|
<template>
|
||||||
|
<div class="qrcode-action-card">
|
||||||
|
<el-image
|
||||||
|
v-if="imageUrl"
|
||||||
|
:src="imageUrl"
|
||||||
|
:preview-src-list="[imageUrl]"
|
||||||
|
preview-teleported
|
||||||
|
fit="cover"
|
||||||
|
class="qrcode-action-card__img"
|
||||||
|
>
|
||||||
|
<template #error>
|
||||||
|
<div class="qrcode-action-card__error">{{ errorText || emptyText }}</div>
|
||||||
|
</template>
|
||||||
|
</el-image>
|
||||||
|
<div v-else class="qrcode-action-card__error">{{ emptyText }}</div>
|
||||||
|
<div v-if="showActionMask" class="qrcode-action-card__mask">
|
||||||
|
<el-button v-if="showPreview" circle :disabled="!imageUrl" @click="handlePreview">
|
||||||
|
<Icon icon="ep:zoom-in" />
|
||||||
|
</el-button>
|
||||||
|
<el-button v-if="showPrint" circle :disabled="!imageUrl || printDisabled" @click="handlePrint">
|
||||||
|
<Icon icon="ep:printer" />
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="showRefresh"
|
||||||
|
circle
|
||||||
|
:loading="refreshLoading"
|
||||||
|
:disabled="refreshDisabled || refreshLoading"
|
||||||
|
@click="handleRefresh"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:refresh" />
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<HiprintPreviewDialog ref="hiprintPreviewDialogRef" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import request from '@/config/axios'
|
||||||
|
import HiprintPreviewDialog from '@/components/HiprintPreviewDialog/index.vue'
|
||||||
|
import { createImageViewer } from '@/components/ImageViewer'
|
||||||
|
import { ElLoading } from 'element-plus'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
const message = useMessage()
|
||||||
|
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
imageUrl?: string
|
||||||
|
printId?: string | number
|
||||||
|
printTitle?: string
|
||||||
|
emptyText?: string
|
||||||
|
refreshUrl?: string
|
||||||
|
refreshMethod?: 'post' | 'put' | 'get'
|
||||||
|
refreshDisabled?: boolean
|
||||||
|
printDisabled?: boolean
|
||||||
|
refreshConfirmText?: string
|
||||||
|
errorText?: string
|
||||||
|
showPreview?: boolean
|
||||||
|
showPrint?: boolean
|
||||||
|
showRefresh?: boolean
|
||||||
|
printAdaptive?: boolean
|
||||||
|
printPaperWidth?: number
|
||||||
|
printPaperHeight?: number
|
||||||
|
printMaxWidth?: number
|
||||||
|
printMaxHeight?: number
|
||||||
|
templateJsonUrl?: string
|
||||||
|
templateJson?: any
|
||||||
|
printData?: Record<string, any>
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
imageUrl: '',
|
||||||
|
printId: '',
|
||||||
|
printTitle: '二维码打印预览',
|
||||||
|
emptyText: '',
|
||||||
|
refreshUrl: '',
|
||||||
|
refreshMethod: 'post',
|
||||||
|
refreshDisabled: false,
|
||||||
|
printDisabled: false,
|
||||||
|
refreshConfirmText: '',
|
||||||
|
errorText: '',
|
||||||
|
showPreview: true,
|
||||||
|
showPrint: true,
|
||||||
|
showRefresh: true,
|
||||||
|
printAdaptive: true,
|
||||||
|
printPaperWidth: 80,
|
||||||
|
printPaperHeight: 80,
|
||||||
|
printMaxWidth: 180,
|
||||||
|
printMaxHeight: 120,
|
||||||
|
templateJsonUrl: '',
|
||||||
|
templateJson: undefined,
|
||||||
|
printData: () => ({})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'refresh-success', data: any): void
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const hiprintPreviewDialogRef = ref()
|
||||||
|
const refreshLoading = ref(false)
|
||||||
|
|
||||||
|
const showActionMask = computed(() => props.showPreview || props.showPrint || props.showRefresh)
|
||||||
|
|
||||||
|
const buildQrcodeTemplateJson = (
|
||||||
|
qrcodeUrl: string,
|
||||||
|
printId: string,
|
||||||
|
imageWidth: number,
|
||||||
|
imageHeight: number,
|
||||||
|
paperHeight: number
|
||||||
|
) => ({
|
||||||
|
panels: [
|
||||||
|
{
|
||||||
|
index: 0,
|
||||||
|
name: 1,
|
||||||
|
width: imageWidth,
|
||||||
|
height: paperHeight,
|
||||||
|
paperHeader: 0,
|
||||||
|
paperFooter: 0,
|
||||||
|
printElements: [
|
||||||
|
{
|
||||||
|
options: {
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
width: imageWidth,
|
||||||
|
height: imageHeight,
|
||||||
|
src: qrcodeUrl,
|
||||||
|
field: 'qrcodeUrl',
|
||||||
|
title: '二维码图片',
|
||||||
|
testData: qrcodeUrl
|
||||||
|
},
|
||||||
|
printElementType: {
|
||||||
|
title: '图片',
|
||||||
|
type: 'image'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
options: {
|
||||||
|
left: 0,
|
||||||
|
top: imageHeight + 2,
|
||||||
|
height: 10,
|
||||||
|
width: imageWidth,
|
||||||
|
testData: printId,
|
||||||
|
title: 'ID',
|
||||||
|
field: 'printId',
|
||||||
|
textAlign: 'center',
|
||||||
|
fontSize: 10
|
||||||
|
},
|
||||||
|
printElementType: {
|
||||||
|
title: '文本',
|
||||||
|
type: 'text'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
paperNumberDisabled: true,
|
||||||
|
paperNumberContinue: true,
|
||||||
|
watermarkOptions: {},
|
||||||
|
panelLayoutOptions: {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
const getImageSize = (src: string) =>
|
||||||
|
new Promise<{ width: number; height: number }>((resolve, reject) => {
|
||||||
|
const img = new Image()
|
||||||
|
img.onload = () => {
|
||||||
|
const width = img.naturalWidth || img.width
|
||||||
|
const height = img.naturalHeight || img.height
|
||||||
|
if (!width || !height) {
|
||||||
|
reject(new Error('invalid image size'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resolve({ width, height })
|
||||||
|
}
|
||||||
|
img.onerror = () => reject(new Error('image load failed'))
|
||||||
|
img.src = src
|
||||||
|
})
|
||||||
|
|
||||||
|
const resolvePrintSize = async (src: string) => {
|
||||||
|
const fallbackWidth = Math.max(20, Number(props.printPaperWidth) || 80)
|
||||||
|
const fallbackHeight = Math.max(20, Number(props.printPaperHeight) || 80)
|
||||||
|
if (!props.printAdaptive) {
|
||||||
|
return { width: fallbackWidth, height: fallbackHeight }
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const size = await getImageSize(src)
|
||||||
|
const ratio = size.width / size.height
|
||||||
|
if (!Number.isFinite(ratio) || ratio <= 0) {
|
||||||
|
return { width: fallbackWidth, height: fallbackHeight }
|
||||||
|
}
|
||||||
|
if (ratio >= 1) {
|
||||||
|
const height = fallbackHeight
|
||||||
|
const width = Math.min(Math.max(fallbackWidth, Math.round(height * ratio)), Number(props.printMaxWidth) || 180)
|
||||||
|
return { width, height }
|
||||||
|
}
|
||||||
|
const width = fallbackWidth
|
||||||
|
const height = Math.min(Math.max(fallbackHeight, Math.round(width / ratio)), Number(props.printMaxHeight) || 120)
|
||||||
|
return { width, height }
|
||||||
|
} catch {
|
||||||
|
return { width: fallbackWidth, height: fallbackHeight }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePreview = () => {
|
||||||
|
if (!props.imageUrl) return
|
||||||
|
createImageViewer({
|
||||||
|
zIndex: 9999999,
|
||||||
|
urlList: [props.imageUrl]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const replaceTemplateValues = (templateJson: any, printData: Record<string, any>) => {
|
||||||
|
if (!templateJson?.panels) return templateJson
|
||||||
|
|
||||||
|
return {
|
||||||
|
...templateJson,
|
||||||
|
panels: templateJson.panels.map((panel: any) => ({
|
||||||
|
...panel,
|
||||||
|
printElements: panel.printElements?.map((element: any) => {
|
||||||
|
if (!element?.options?.qid) return element
|
||||||
|
|
||||||
|
const qid = element.options.qid
|
||||||
|
const value = printData[qid]
|
||||||
|
|
||||||
|
if (value === undefined || value === null) return element
|
||||||
|
|
||||||
|
const newOptions = { ...element.options }
|
||||||
|
|
||||||
|
if (qid === 'qrcodeUrl') {
|
||||||
|
newOptions.src = value
|
||||||
|
newOptions.testData = value
|
||||||
|
} else {
|
||||||
|
newOptions.field = qid
|
||||||
|
if (newOptions.testData === undefined || newOptions.testData === '') {
|
||||||
|
newOptions.testData = String(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...element,
|
||||||
|
options: newOptions
|
||||||
|
}
|
||||||
|
}) || []
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePrint = async () => {
|
||||||
|
if (!props.imageUrl || !props.showPrint) return
|
||||||
|
|
||||||
|
let templateJson: any
|
||||||
|
let printData: Record<string, any>
|
||||||
|
|
||||||
|
printData = {
|
||||||
|
qrcodeUrl: props.imageUrl,
|
||||||
|
printId: props.printId === undefined || props.printId === null ? '' : String(props.printId),
|
||||||
|
...props.printData
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.templateJson) {
|
||||||
|
templateJson = replaceTemplateValues(props.templateJson, printData)
|
||||||
|
} else if (props.templateJsonUrl) {
|
||||||
|
try {
|
||||||
|
const response = await request.get({ url: props.templateJsonUrl })
|
||||||
|
templateJson = typeof response.data === 'string' ? JSON.parse(response.data) : response.data
|
||||||
|
templateJson = replaceTemplateValues(templateJson, printData)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取打印模板失败', error)
|
||||||
|
message.error('获取打印模板失败')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const printSize = await resolvePrintSize(props.imageUrl)
|
||||||
|
const imageWidth = printSize.width
|
||||||
|
const imageHeight = printSize.height
|
||||||
|
const printId = props.printId === undefined || props.printId === null ? '' : String(props.printId)
|
||||||
|
const idAreaHeight = printId ? 14 : 0
|
||||||
|
const paperHeight = imageHeight + idAreaHeight
|
||||||
|
|
||||||
|
templateJson = buildQrcodeTemplateJson(props.imageUrl, printId, imageWidth, imageHeight, paperHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
const paperSize = templateJson?.panels?.[0] ? {
|
||||||
|
width: templateJson.panels[0].width,
|
||||||
|
height: templateJson.panels[0].height
|
||||||
|
} : { width: 80, height: 80 }
|
||||||
|
|
||||||
|
hiprintPreviewDialogRef.value?.open({
|
||||||
|
title: props.printTitle,
|
||||||
|
printData,
|
||||||
|
templateJson,
|
||||||
|
withDefaultQrcodeLayout: false,
|
||||||
|
paperSize
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleRefresh = async () => {
|
||||||
|
if (!props.refreshUrl || props.refreshDisabled || !props.showRefresh) return
|
||||||
|
try {
|
||||||
|
await message.confirm(props.refreshConfirmText || '确认刷新二维码吗?')
|
||||||
|
} catch {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
refreshLoading.value = true
|
||||||
|
const loading = ElLoading.service({
|
||||||
|
lock: true,
|
||||||
|
text: t('common.loading'),
|
||||||
|
background: 'rgba(0, 0, 0, 0.3)'
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
let data
|
||||||
|
if (props.refreshMethod === 'get') {
|
||||||
|
data = await request.get({ url: props.refreshUrl })
|
||||||
|
} else if (props.refreshMethod === 'put') {
|
||||||
|
data = await request.put({ url: props.refreshUrl })
|
||||||
|
} else {
|
||||||
|
data = await request.post({ url: props.refreshUrl })
|
||||||
|
}
|
||||||
|
emit('refresh-success', data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
} finally {
|
||||||
|
loading.close()
|
||||||
|
refreshLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.qrcode-action-card {
|
||||||
|
position: relative;
|
||||||
|
height: 150px;
|
||||||
|
width: fit-content;
|
||||||
|
min-width: 150px;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid var(--el-border-color-lighter);
|
||||||
|
background: var(--el-fill-color-blank);
|
||||||
|
}
|
||||||
|
|
||||||
|
.qrcode-action-card__img {
|
||||||
|
height: 150px;
|
||||||
|
width: auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qrcode-action-card__error {
|
||||||
|
height: 150px;
|
||||||
|
min-width: 150px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: var(--el-text-color-secondary);
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 0 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qrcode-action-card__mask {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 10px;
|
||||||
|
background: rgba(0, 0, 0, 0.35);
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qrcode-action-card:hover .qrcode-action-card__mask {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue