chore(deps): 新增 apk-meta-parser、jszip、spark-md5 依赖,新增应用分类和安装包 API,重构设备详情抽屉组件

This commit is contained in:
TongTongStudio
2026-08-07 12:19:46 +08:00
parent aba4d2d3bc
commit 96a0b12582
16 changed files with 1915 additions and 1998 deletions

View File

@@ -1,30 +1,31 @@
import UserAPI from "@/api/system/user";
import type { UserForm } from "@/types/api";
import DeviceAPI from "@/api/system/device";
import type { DeviceForm } from "@/api/system/device/types";
import type { IModalConfig } from "@/components/DeviceSn/types";
import { deptArr, roleArr } from "./options";
const modalConfig: IModalConfig<UserForm> = {
permPrefix: "sys:user",
const modalConfig: IModalConfig<DeviceForm> = {
permPrefix: "sys:device",
dialog: {
title: "新增用户",
title: "新增设备",
width: 800,
draggable: true,
},
form: {
labelWidth: 100,
},
formAction: UserAPI.create,
formAction(data) {
return DeviceAPI.create(data);
},
beforeSubmit(data) {
console.warn("提交之前处理", data);
return data;
},
formItems: [
{
label: "用户名",
prop: "username",
rules: [{ required: true, message: "用户名不能为空", trigger: "blur" }],
label: "设备SN",
prop: "serialno",
rules: [{ required: true, message: "设备SN不能为空", trigger: "blur" }],
type: "input",
attrs: {
placeholder: "请输入用户名",
placeholder: "请输入设备序列号",
},
col: {
xs: 24,
@@ -32,12 +33,12 @@ const modalConfig: IModalConfig<UserForm> = {
},
},
{
label: "用户昵称",
prop: "nickname",
rules: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }],
label: "设备型号",
prop: "snModel",
rules: [{ required: true, message: "设备型号不能为空", trigger: "blur" }],
type: "input",
attrs: {
placeholder: "请输入用户昵称",
placeholder: "请输入设备型号",
},
col: {
xs: 24,
@@ -45,48 +46,21 @@ const modalConfig: IModalConfig<UserForm> = {
},
},
{
label: "所属部门",
prop: "deptId",
rules: [{ required: true, message: "所属部门不能为空", trigger: "change" }],
type: "tree-select",
attrs: {
placeholder: "请选择所属部门",
data: deptArr,
filterable: true,
"check-strictly": true,
"render-after-expand": false,
},
// async initFn(formItem) {
// // 注意:如果initFn函数不是箭头函数,this会指向此配置项对象,那么也就可以用this来替代形参formItem
// formItem.attrs.data = await DeptAPI.getOptions();
// },
},
{
type: "custom",
label: "性别",
prop: "gender",
initialValue: 1,
attrs: { style: { width: "100%" } },
},
{
label: "角色",
prop: "roleIds",
rules: [{ required: true, message: "用户角色不能为空", trigger: "change" }],
type: "select",
attrs: {
placeholder: "请选择",
multiple: true,
},
options: roleArr,
initialValue: [],
// async initFn(formItem) {
// formItem.options = await RoleAPI.getOptions();
// },
},
{
label: "设备昵称",
prop: "snName",
rules: [{ required: true, message: "设备昵称不能为空", trigger: "blur" }],
type: "input",
attrs: {
placeholder: "请输入内容",
},
col: {
xs: 24,
sm: 12,
},
},
{
label: "手机号码",
prop: "mobile",
prop: "snMobile",
rules: [
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
@@ -94,25 +68,50 @@ const modalConfig: IModalConfig<UserForm> = {
trigger: "blur",
},
],
type: "input",
attrs: {
placeholder: "请输入手机号码",
maxlength: 11,
},
col: {
xs: 24,
sm: 12,
},
},
{
label: "邮箱",
prop: "email",
rules: [
{
pattern: /\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}/,
message: "请输入正确的邮箱地址",
trigger: "blur",
},
],
label: "IMEI",
prop: "snImei",
type: "input",
attrs: {
placeholder: "请输入邮箱",
maxlength: 50,
placeholder: "请输入设备IMEI",
},
col: {
xs: 24,
sm: 12,
},
},
{
label: "设备类型",
prop: "deviceType",
type: "input",
attrs: {
placeholder: "请输入设备类型",
},
col: {
xs: 24,
sm: 12,
},
},
{
label: "来源",
prop: "source",
type: "input",
attrs: {
placeholder: "请输入设备来源",
},
col: {
xs: 24,
sm: 12,
},
},
{
@@ -120,17 +119,11 @@ const modalConfig: IModalConfig<UserForm> = {
prop: "status",
type: "radio",
options: [
{ label: "正常", value: 1 },
{ label: "启用", value: 1 },
{ label: "禁用", value: 0 },
],
initialValue: 1,
},
{
type: "custom",
label: "二级弹窗",
prop: "openModal",
slotName: "openModal",
},
],
};

View File

@@ -1,87 +1,69 @@
import UserAPI from "@/api/system/user";
import type { UserForm } from "@/api/system/user/types";
import { reactive } from "vue";
import DeviceAPI from "@/api/system/device";
import type { DeviceForm } from "@/api/system/device/types";
import type { IModalConfig } from "@/components/DeviceSn/types";
import { DeviceEnum } from "@/enums/settings";
import { useAppStore } from "@/stores";
import { deptArr, roleArr } from "./options";
const modalConfig: IModalConfig<UserForm> = {
permPrefix: "sys:user",
/** 只读输入框配置(展示常用参数,不可编辑) */
const readonlyInput = (placeholder = "系统自动填充") => ({
type: "input" as const,
attrs: {
placeholder,
readonly: true,
disabled: true,
},
});
const modalConfig: IModalConfig<DeviceForm> = {
permPrefix: "sys:device",
component: "drawer",
drawer: {
title: "修改用户",
title: "修改设备",
size: useAppStore().device === DeviceEnum.MOBILE ? "80%" : 500,
},
pk: "id",
// 编辑只回传可修改字段,其余保持不变
beforeSubmit(data) {
console.warn("beforeSubmit", data);
return {
id: data.id,
serialno: data.serialno,
snName: data.snName,
status: data.status,
} as DeviceForm;
},
formAction(data) {
return UserAPI.update(data.id as string, data);
return DeviceAPI.update(data.id as string, data);
},
formItems: [
{
label: "用户名",
prop: "username",
rules: [{ required: true, message: "用户名不能为空", trigger: "blur" }],
label: "设备SN",
prop: "serialno",
type: "input",
attrs: {
placeholder: "请输入用户名",
placeholder: "设备序列号",
readonly: true,
},
},
{
label: "用户昵称",
prop: "nickname",
rules: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }],
label: "设备型号",
prop: "snModel",
rules: [{ required: true, message: "设备型号不能为空", trigger: "blur" }],
...readonlyInput("设备型号"),
},
{
label: "设备昵称",
prop: "snName",
rules: [{ required: true, message: "设备昵称不能为空", trigger: "blur" }],
type: "input",
attrs: {
placeholder: "请输入用户昵称",
placeholder: "请输入设备昵称",
maxlength: 50,
},
},
{
label: "所属部门",
prop: "deptId",
rules: [{ required: true, message: "所属部门不能为空", trigger: "blur" }],
type: "tree-select",
attrs: {
placeholder: "请选择所属部门",
data: deptArr, // setupVue会自动解包ref不需要.value
filterable: true,
"check-strictly": true,
"render-after-expand": false,
},
// async initFn(formItem) {
// // 注意:如果initFn函数不是箭头函数,this会指向此配置项对象,那么也就可以用this来替代形参formItem
// formItem.attrs.data = await DeptAPI.getOptions();
// },
},
{
type: "custom",
label: "性别",
prop: "gender",
initialValue: 1,
attrs: { style: { width: "100%" } },
},
{
label: "角色",
prop: "roleIds",
rules: [{ required: true, message: "用户角色不能为空", trigger: "blur" }],
type: "select",
attrs: {
placeholder: "请选择",
multiple: true,
},
options: roleArr,
initialValue: [],
// async initFn(formItem) {
// formItem.options = await RoleAPI.getOptions();
// },
},
{
type: "input",
label: "手机号码",
prop: "mobile",
prop: "snMobile",
rules: [
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
@@ -89,26 +71,32 @@ const modalConfig: IModalConfig<UserForm> = {
trigger: "blur",
},
],
attrs: {
placeholder: "请输入手机号码",
maxlength: 11,
},
...readonlyInput("绑定手机号"),
},
{
label: "邮箱",
prop: "email",
rules: [
{
pattern: /\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}/,
message: "请输入正确的邮箱地址",
trigger: "blur",
},
],
type: "input",
attrs: {
placeholder: "请输入邮箱",
maxlength: 50,
},
label: "IMEI",
prop: "snImei",
...readonlyInput("设备IMEI"),
},
{
label: "设备类型",
prop: "deviceType",
...readonlyInput("设备类型"),
},
{
label: "来源",
prop: "source",
...readonlyInput("设备来源"),
},
{
label: "激活时间",
prop: "activationTime",
...readonlyInput("激活时间"),
},
{
label: "最后上线",
prop: "lastOnline",
...readonlyInput("最后上线时间"),
},
{
label: "状态",
@@ -116,7 +104,7 @@ const modalConfig: IModalConfig<UserForm> = {
type: "switch",
attrs: {
inlinePrompt: true,
activeText: "正常",
activeText: "启用",
inactiveText: "禁用",
activeValue: 1,
inactiveValue: 0,

View File

@@ -103,7 +103,6 @@ const {
handleResetClick,
handleAddClick,
handleEditClick,
handleViewClick,
handleSubmitClick,
handleExportClick,
handleSearchClick,
@@ -125,12 +124,8 @@ function handleReturnClick() {
// 表格工具
const handleOperateClick = (data: IObject) => {
if (data.name === "detail") {
editModalConfig.drawer = { ...editModalConfig.drawer, title: "查看" };
handleViewClick(data.row, async () => {
// 加载下拉数据源,建议在初始化配置项"initFn 中加载,避免多次请求
// editModalConfig.formItems[2]!.attrs!.data = await DeptAPI.getOptions();
return await DeviceAPI.getFormData(data.row.serialno as string); // 根据SN获取详情
});
// 打开设备详情抽屉,读取常用参数
handleSerialnoClick(data.row);
} else if (data.name === "edit") {
editModalConfig.drawer = { ...editModalConfig.drawer, title: "修改" };
handleEditClick(data.row, async () => {