ソースを参照

服装底库

master
suyanyan 2ヶ月前
コミット
31fb9d04f8
6個のファイルの変更472行の追加51行の削除
  1. +10
    -46
      SafeCampus.WEB/src/api/interface/sys/usermanage/clothing.ts
  2. +5
    -5
      SafeCampus.WEB/src/api/modules/usermanage/clothing.ts
  3. +2
    -0
      SafeCampus.WEB/src/typings/props.d.ts
  4. +156
    -0
      SafeCampus.WEB/src/views/userManage/clothing/components/form/index.vue
  5. +105
    -0
      SafeCampus.WEB/src/views/userManage/clothing/components/form1/index.vue
  6. +194
    -0
      SafeCampus.WEB/src/views/userManage/clothing/index.vue

+ 10
- 46
SafeCampus.WEB/src/api/interface/sys/usermanage/clothing.ts ファイルの表示

@@ -11,8 +11,6 @@
* 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为不要删除和修改作者声明。
* 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关
*/

import { ReqPage } from "@/api";
/**
* @Description: 服装底库管理接口
* @Author: syy
@@ -22,54 +20,20 @@ import { ReqPage } from "@/api";
export namespace SysUserCloth {
// 服装底库树
export interface Page {
clothSetId: number | string;
clothSetName: number | string;
clothSetId?: number | string;
clothSetName?: number | string;
}

/** id请求参数 */
export interface ReqName {
name: number | string;
}
/** 底库信息 */
export interface ClassPage {
personSetId?: string | number | undefined;
personSetName?: string | undefined;
id?: string | undefined;
name?: string | undefined;
personId?: string | undefined | number;
}
/** 人脸信息 */
export interface SysUserAvatar {
/** 人脸 */
personId?: string | undefined | number;
faceId?: string | number;
faceUrl: string;
uid?: string | number;
export interface list {
clothUrl: string;
clothId: number | string;
clothSetId: string;
}
// 人脸删除
export interface SysUserFace {
personId: string | undefined;
faceIds: Array<string | number>;
}

/** 用户信息 */
export interface SysUserClothInfo {
/** 人员id */
personId?: string;
/** 姓名 */
name?: string;
/** 年龄 */
age?: number | string;
/** 性别 */
gender?: string;
/** 手机 */
phone?: string;
/** 扩展字段 */
extData?: string;
/** 人脸 */
faces: Array<SysUserAvatar>;
/** 分组 */
personSets: Array<ClassPage>;
personSetId?: number | string;
clothSetId: number | string;
clothSetName: number | string;
/** 列表 */
clothes?: Array<list>;
}
}

+ 5
- 5
SafeCampus.WEB/src/api/modules/usermanage/clothing.ts ファイルの表示

@@ -34,24 +34,24 @@ const userManageClothApi = {
return http.delete("deleteClothDataBaseD", params);
},
/** 新增服装底库 */
addClothDataBaseA(params: SysUserCloth.ReqName) {
addClothDataBaseA(params: SysUserCloth.Page) {
return http.post("addClothDataBaseA", params);
},
/** 更新服装底库 */
update(params: SysUserCloth.SysUserPerInfo) {
update(params: SysUserCloth.Page) {
return http.put("updateClothU", params);
},

/** 服装图片上传 */
uploadFile(params: SysUserCloth.SysUserAvatar) {
uploadFile(params: any) {
return http.post("uploadFile", params);
},
/** 新增服装 */
add(params: SysUserCloth.SysUserPerInfo) {
add(params: any) {
return http.post("addClothA", params);
},
/** 删除服装 */
delete(params: SysUserCloth.SysUserFace) {
delete(params: SysUserCloth.list) {
return http.post("deleteClothD", params);
}
};


+ 2
- 0
SafeCampus.WEB/src/typings/props.d.ts ファイルの表示

@@ -27,6 +27,8 @@ declare namespace FormProps {
disabled?: boolean;
/** 行内表单模式 */
inline?: boolean;
// 树数据
treeAllData?: Array<any>;
/** 表单布局 */
successful?: () => void;
}


+ 156
- 0
SafeCampus.WEB/src/views/userManage/clothing/components/form/index.vue ファイルの表示

@@ -0,0 +1,156 @@
<!--
* @Description: 表单
* @Author: syy
* @Date: 2023-12-15 15:45:59
-->
<template>
<div>
<form-container v-model="visible" :title="`${sysUserProps.opt}人员`" form-size="500px" @close="onClose">
<el-form
ref="sysUserFormRef"
:rules="rules"
:disabled="sysUserProps.disabled"
:model="sysUserProps.record"
:hide-required-asterisk="sysUserProps.disabled"
label-width="auto"
label-suffix=" :"
>
<div>
<el-row :gutter="16">
<el-col :span="24">
<s-form-item label="所属服装库" prop="clothSetId">
<s-select
v-model="sysUserProps.record.clothSetId"
:options="sysUserProps.treeAllData"
label="clothSetName"
value="clothSetId"
></s-select>
</s-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="24">
<s-form-item label="上传服装" prop="faces">
<el-upload
class="avatar-uploader"
action="/api/business/clothApi/uploadFile"
:show-file-list="false"
:on-success="handleAvatarSuccess"
accept=".jpg, .jpeg, .png"
:headers="{
Authorization: `${TokenEnum.TOKEN_PREFIX} ${accessToken}`
}"
>
<img v-if="sysUserProps.record.clothUrl" :src="sysUserProps.record.clothUrl" class="avatar" />
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
</el-upload>
</s-form-item>
</el-col>
</el-row>
</div>
</el-form>
<template #footer>
<el-button @click="onClose"> 取消 </el-button>
<el-button v-show="!sysUserProps.disabled" type="primary" @click="handleSubmit"> 确定 </el-button>
</template>
</form-container>
</div>
</template>

<script setup lang="ts" name="SysUserClothForm">
import { SysUserCloth, userManageClothApi } from "@/api";
import { FormOptEnum } from "@/enums";
import { required } from "@/utils/formRules";
import { FormInstance } from "element-plus";
import { useUserStore } from "@/stores/modules";
import type { UploadProps } from "element-plus";
import { TokenEnum } from "@/enums";
const visible = ref(false); //是否显示表单
const activeName = ref("basic");
const userStore = useUserStore();
const { accessToken } = userStore;
// 表单参数
const sysUserProps = reactive<FormProps.Base<SysUserCloth.list>>({
opt: FormOptEnum.ADD,
record: {},
treeAllData: [],
disabled: false
});

// 表单验证规则
const rules = reactive({
clothSetId: [required("请选择所属服装库")],
clothUrl: [required("请上传服装")]
});

const handleAvatarSuccess: UploadProps["onSuccess"] = (response: any) => {
if (response.code === 200) {
sysUserProps.record.clothUrl = response.data;
}
};
/**
* 打开表单
* @param props 表单参数
*/
function onOpen(props: FormProps.Base<SysUserCloth.list>) {
Object.assign(sysUserProps, props); //合并参数
visible.value = true; //显示表单
sysUserProps.record = props.record;
}

// 提交数据(新增/编辑)
const sysUserFormRef = ref<FormInstance>();
/** 提交表单 */
async function handleSubmit() {
sysUserFormRef.value?.validate(async valid => {
if (!valid) return; //表单验证失败
await userManageClothApi
.add(sysUserProps.record)
.then(() => {
sysUserProps.successful!(); //调用父组件的successful方法
})
.finally(() => {
onClose();
});
});
}

/** 关闭表单*/
function onClose() {
visible.value = false;
activeName.value = "basic";
}

// 暴露给父组件的方法
defineExpose({
onOpen
});
</script>

<style lang="scss" scoped>
.avatar-uploader .avatar {
display: block;
width: 178px;
height: 178px;
}
</style>
<style>
.avatar-uploader .el-upload {
position: relative;
overflow: hidden;
cursor: pointer;
border: 1px dashed var(--el-border-color);
border-radius: 6px;
transition: var(--el-transition-duration-fast);
}
.avatar-uploader .el-upload:hover {
border-color: var(--el-color-primary);
}
.el-icon.avatar-uploader-icon {
width: 178px;
height: 178px;
font-size: 28px;
color: #8c939d;
text-align: center;
}
</style>

+ 105
- 0
SafeCampus.WEB/src/views/userManage/clothing/components/form1/index.vue ファイルの表示

@@ -0,0 +1,105 @@
<!--
* @Description: 表单
* @Author: syy
* @Date: 2023-12-18 15:45:59
-->
<template>
<div>
<form-container v-model="visibleClass" :title="`${sysUserProps.opt}班级`" form-size="400px" @close="onClose">
<el-form
ref="sysUserFormRef"
:rules="rules"
:disabled="sysUserProps.disabled"
:model="sysUserProps.record"
:hide-required-asterisk="sysUserProps.disabled"
label-width="auto"
label-suffix=" :"
>
<div>
<el-row :gutter="16">
<el-col :span="22">
<s-form-item label="服装库名称" prop="clothSetName">
<s-input v-model="sysUserProps.record.clothSetName"></s-input>
</s-form-item>
</el-col>
</el-row>
</div>
</el-form>
<template #footer>
<el-button @click="onClose"> 取消 </el-button>
<el-button v-show="!sysUserProps.disabled" type="primary" @click="handleSubmit"> 确定 </el-button>
</template>
</form-container>
</div>
</template>

<script setup lang="ts" name="SysUserClothDk">
import { ref } from "vue";
import { userManageClothApi, SysUserCloth } from "@/api";
import { FormOptEnum } from "@/enums";
import { required } from "@/utils/formRules";
import { FormInstance } from "element-plus";

const visibleClass = ref(false); //是否显示表单
// 表单参数
const sysUserProps = reactive<FormProps.Base<SysUserCloth.Page>>({
opt: FormOptEnum.ADD,
record: {},
disabled: false
});
// 表单验证规则
const rules = reactive({
clothSetName: [required("请输入服装库名称")]
});

/**
* 打开表单
* @param props 表单参数
*/
function onOpen(props: FormProps.Base<SysUserCloth.Page>) {
Object.assign(sysUserProps, props); //合并参数
visibleClass.value = true; //显示表单
sysUserProps.record = props.record;
}

// 提交数据(新增/编辑)
const sysUserFormRef = ref<FormInstance>();
/** 提交表单 */
async function handleSubmit() {
sysUserFormRef.value?.validate(async valid => {
if (!valid) return; //表单验证失败
//提交表单
if (sysUserProps.record.clothSetId) {
await userManageClothApi
.update(sysUserProps.record)
.then(() => {
sysUserProps.successful!(); //调用父组件的successful方法
})
.finally(() => {
onClose();
});
} else {
await userManageClothApi
.addClothDataBaseA(sysUserProps.record)
.then(() => {
sysUserProps.successful!(); //调用父组件的successful方法
})
.finally(() => {
onClose();
});
}
});
}

/** 关闭表单*/
function onClose() {
visibleClass.value = false;
}

// 暴露给父组件的方法
defineExpose({
onOpen
});
</script>

<style lang="scss" scoped></style>

+ 194
- 0
SafeCampus.WEB/src/views/userManage/clothing/index.vue ファイルの表示

@@ -0,0 +1,194 @@
<!--
* @Description: 服装库管理
* @Author: syy
* @Date: 2024-7-18
-->
<template>
<div class="main-box">
<TreeFilter
ref="treeFilter"
label="clothSetName"
id="clothSetId"
width="300px"
:show-all="false"
:request-api="userManageClothApi.getList"
@change="changeTreeFilter"
>
<template v-slot:header>
<s-button suffix="服装库" @click="addClass(FormOptEnum.ADD)" style="margin-bottom: 15px" />
</template>
<template v-slot:label="{ row }">
<span class="custom-tree-node">
<span>{{ row.node.label }}</span>
<span>
<a @click="addClass(FormOptEnum.EDIT, row.node.data)">
<el-icon><Edit /></el-icon>
</a>
<a style="margin-left: 8px" @click="addDelete(row.node.data.clothSetId, '删除服装库')">
<el-icon><Delete /></el-icon>
</a>
</span>
</span>
</template>
</TreeFilter>
<div class="table-box">
<ProTable ref="proTable" title="服装库管理" :columns="columns" rowKey="clothId" :data="tableData.clothes">
<!-- 表格 header 按钮 -->
<template #tableHeader="scope">
<s-button suffix="服装" @click="onOpen(FormOptEnum.ADD, { clothSetId: clothSetId }, treeFilter.treeAllData)" />
<s-button
type="danger"
:opt="FormOptEnum.DELETE"
plain
suffix="服装"
:disabled="!scope.isSelected"
@click="onDelete(scope.selectedListIds, '删除所选服装')"
/>
</template>
<!-- 表格操作栏 -->
<template #operation="scope">
<el-space>
<s-button link :opt="FormOptEnum.DELETE" @click="onDelete([scope.row.clothId], `删除服装`)" />
</el-space>
</template>
</ProTable>
</div>
<!-- 人员新增/编辑表单 -->
<Form ref="formRef"></Form>
<!-- 班级新增/编辑表单 -->
<Form1 ref="formRefC" />
<!-- 预览头像 -->
<el-dialog v-model="visible" title="查看头像" width="830px" :before-close="handleClose">
<div>
<img style="width: 100%" class="detailpic" :src="faceUrl" alt="" />
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="visible = false">关闭</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup lang="tsx" name="SysUserClothing">
import { userManageClothApi,userClothButtonCode,SysUserCloth } from "@/api";
import { useHandleData } from "@/hooks/useHandleData";
import { FormOptEnum } from "@/enums";
import Form from "./components/form/index.vue";
import Form1 from "./components/form1/index.vue";
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
import TreeFilter from "@/components/TreeFilter/index.vue";
import { useUserStore } from "@/stores/modules";
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
const faceUrl = ref('');
const visible = ref(false); //是否显示人员表单
const proTable = ref<ProTableInstance>();
const treeFilter = ref<any>({});
const userStore = useUserStore();
const { accessToken } = userStore;
const tableData = ref<any>([])
// 表格配置项
const columns: ColumnProps<SysUserCloth.list>[] = [
{ type: "selection", fixed: "left", width: 50 },
{
prop: "clothUrl",
label: "服装图",
render: scope => {
return (
<img src={scope.row.clothUrl} onClick={() => viewHeadImage(scope)} style='width:50px;height:50px' alt=''/>
);
}
},
{ prop: "operation", label: "操作", width: 250, fixed: "right" }
];
const viewHeadImage = (scope: any) => {
faceUrl.value = scope.row.clothUrl;
visible.value = true
};
const handleClose = () => {
visible.value = false;
};
// 人员表单引用
const formRef = ref<InstanceType<typeof Form> | null>(null);
// 班级表单引用
const formRefC = ref<InstanceType<typeof Form1> | null>(null);
/**
* 打开服装表单
* @param opt 操作类型
* @param record 记录
*/
function onOpen(opt: FormOptEnum, record: {},treeAllData:any) {
formRef.value?.onOpen({ opt: opt, record: record,treeAllData:treeAllData, successful: RefreshTable });
}

/**
* 打开服装库表单
* @param opt 操作类型
* @param record 记录
*/

function addClass(opt: FormOptEnum, record: {} | SysUserCloth.list = {}) {
formRefC.value?.onOpen({ opt: opt, record: record, successful: RefreshTree });
}
/**
* 服装库删除
* @param ids id数组
*/
async function addDelete(clothSetId: string[],msg: string) {
// 二次确认 => 请求api => 刷新表格
await useHandleData(userManageClothApi.deleteClothDataBaseD, { clothSetId }, msg);
RefreshTree(); //刷新表格
}

/**
* 服装删除
* @param ids id数组
*/
async function onDelete(ids: string[], msg: string) {
// 二次确认 => 请求api => 刷新表格
await useHandleData(userManageClothApi.delete, {clothId: ids.join(","), clothSetId:tableData.value.clothSetId}, msg);
RefreshTable(); //刷新表格
}

// 刷新表格
const RefreshTable = () => {
getList(clothSetId.value)
}
// 刷新表格+树
const RefreshTree = () => {
getList(clothSetId.value)
treeFilter.value?.refresh(); //刷新树形筛选器
}



/** 服装库切换切换 */
const clothSetId = ref<number | string>()
function changeTreeFilter(val: number | string) {
clothSetId.value = val
proTable.value!.pageable.pageNum = 1;
getList(val)
}
// 获取列表
const getList = (clothSetId:any)=>{
userManageClothApi.page({clothSetId:clothSetId}).then((resp:any)=>{
if(resp.code == 200){
tableData.value = resp.data
}
})
}
</script>
<style scoped lang="scss">
.table-box {
width: 100%;
height: 100%;
}
.custom-tree-node {
display: flex;
flex: 1;
align-items: center;
justify-content: space-between;
padding-right: 8px;
font-size: 14px;
}
</style>

読み込み中…
キャンセル
保存