2026-03-23 06:14:31 +08:00

320 lines
9.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="system-menu-container layout-padding">
<ProTable ref="tableRef" :request-api="projectPageGet" :columns="columns" :pagination="true" :tool-button="false" :initParam="initParam">
<template #tools>
<el-button v-auth="'project:add'" type="primary" icon="ele-Plus" @click="onOpenMenu()"> 新增 </el-button>
</template>
<template #index="scope">
{{ scope.$index + 1 }}
</template>
<template #projectTypeId="scope">
{{ scope.row.projectTypeName }}
</template>
<template #completionCount="scope">
{{ scope.row.projectTypeId == '1003' || scope.row.projectTypeId == '1004' ? 1 : scope.row.completionCount }}
</template>
<template #action="scope">
<el-button v-auth="'project:edit'" icon="ele-Edit" size="small" text type="primary" @click="onOpenMenu(scope.row)"> 编辑 </el-button>
<el-popconfirm title="确认删除吗?" @confirm="onDeleteMenu(scope.row.id)">
<template #reference>
<el-button v-auth="'project:delete'" icon="ele-Delete" size="small" text type="danger"> 删除 </el-button>
</template>
</el-popconfirm>
<el-button v-auth="'project:detail'" size="small" text type="primary" @click="onOpenMenu(scope.row)"> 查看详情 </el-button>
</template>
</ProTable>
<!-- 弹窗 -->
<el-dialog :title="dialogTitle" v-model="isShowDialog" width="1100px">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="150px" style="width: 90%; margin-bottom: 30px" v-if="isShowDialog">
<!-- 项目名称 -->
<el-form-item label="项目名称:" prop="name">
<el-input v-model="formData.name" placeholder="请输入项目名称"></el-input>
</el-form-item>
<!-- 项目类型 -->
<el-form-item label="项目类型:" prop="projectTypeId">
<el-select v-model="formData.projectTypeId" placeholder="请选择项目类型" style="width: 100%">
<el-option label="个人速度" :value="1003"></el-option>
<el-option label="个人花样" :value="1004"></el-option>
<el-option label="团队速度" :value="1005"></el-option>
<el-option label="团队花样" :value="1006"></el-option>
</el-select>
</el-form-item>
<!-- 完成人数 -->
<el-form-item label="完成人数:" prop="completionCount" v-if="formData.projectTypeId == 1005 || formData.projectTypeId == 1006">
<el-input v-model="formData.completionCount" placeholder="请输入完成人数"></el-input>
</el-form-item>
<!-- 组别 -->
<div v-if="formData.projectTypeId == 1005 || formData.projectTypeId == 1006">
<el-form-item
:label="'组别' + (index + 1) + ':'"
prop="groups"
v-for="(group, index) in formData.groups"
:key="index"
:rules="{
validator: (rule, value, callback) => {
console.log(value);
if (!value[index].groupName) {
callback(new Error('请输入组别名'));
}
if (!value[index].birthDateStart) {
callback(new Error('请选择出生日期开始'));
}
if (!value[index].birthDateEnd) {
callback(new Error('请选择出生日期结束'));
}
if (!value[index].gender) {
callback(new Error('请选择性别'));
} else {
callback();
}
},
trigger: 'blur',
}"
>
<el-input v-model="group.groupName" placeholder="输入组别名" style="width: 100px; margin-right: 18px"></el-input>
<el-date-picker v-model="group.birthDateStart" type="date" placeholder="出生日期开始" style="margin-right: 18px"></el-date-picker>
<el-date-picker v-model="group.birthDateEnd" type="date" placeholder="出生日期结束" style="margin-right: 18px"></el-date-picker>
<el-select v-model="group.gender" placeholder="性别" style="width: 100px">
<el-option label="男" :value="1"></el-option>
<el-option label="女" :value="2"></el-option>
<el-option label="不限" :value="0"></el-option>
</el-select>
<el-button
circle
@click="removeGroup(index)"
style="margin-left: 30px"
size="small"
icon="Minus"
v-if="index == formData.groups.length - 1 && index != 0"
></el-button>
</el-form-item>
<el-button @click="addGroup" icon="Plus" style="margin: 20px 0px 20px 150px; width: 85%" dashed></el-button>
</div>
<!-- 费用 -->
<el-form-item label="费用:" prop="fee">
<el-input v-model="formData.fee" placeholder="请输入费用" class="fee-input">
<template slot="append">元</template>
</el-input>
</el-form-item>
<!-- 时长 -->
<el-form-item label="时长:" prop="duration">
<div class="duration-row">
<el-input v-model="formData.durationMinutes" placeholder="分"></el-input>
<span class="duration-label">分</span>
<span class="duration-separator">--</span>
<el-input v-model="formData.durationSeconds" placeholder="秒"></el-input>
<span class="duration-label">秒</span>
</div>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="onCancel">取消</el-button>
<el-button type="primary" @click="onSubmit">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup name="project">
import { defineAsyncComponent, ref, reactive } from 'vue';
import { ElMessage, ElForm } from 'element-plus';
import SysMenuApi from '/@/api/SysMenuApi';
import { auths } from '/@/utils/authFunction';
import ProTable from '/@/components/ProTable/index.vue';
import { projectPageGet, projectAddPost, projectEditPut, projectDeleteDelete , projectDetailGet } from '/@/api/match/project';
// 定义表单引用类型
const formRef = ref();
const initParam = ref({
refresh: true,
});
const addGroup = () => {
formData.value.groups.push({
groupName: '',
birthDateStart: '',
birthDateEnd: '',
gender: '',
});
};
const removeGroup = () => {
formData.value.groups.pop();
};
const formData = ref({
name: '',
projectTypeId: '',
completionCount: '',
fee: '',
durationMinutes: '0',
durationSeconds: '0',
groups: [
{
groupName: '',
birthDateStart: '',
birthDateEnd: '',
gender: '',
},
],
});
const formRules = ref({
name: [{ required: true, message: '请输入项目名称', trigger: 'blur' }],
projectTypeId: [{ required: true, message: '请选择项目类型', trigger: 'change' }],
completionCount: [{ required: true, message: '请输入完成人数', trigger: 'blur' }],
description: [{ required: true, message: '请输入项目描述', trigger: 'blur' }],
fee: [{ required: true, message: '请输入费用', trigger: 'blur' }],
durationMinutes: [{ required: true, message: '请输入时长(分)', trigger: 'blur' }],
durationSeconds: [{ required: true, message: '请输入时长(秒)', trigger: 'blur' }],
});
const columns = ref([
{
prop: 'index',
label: '序号',
align: 'center',
},
{
prop: 'name',
label: '项目名称',
align: 'center',
search: {
el: 'input',
},
},
{
prop: 'projectTypeId',
label: '项目类型',
search: {
el: 'select',
},
enum: [
{ label: '全部', value: 0 },
{ label: '团队速度', value: 1001 },
{ label: '团队花样', value: 1002 },
{ label: '个人速度', value: 1003 },
{ label: '个人花样', value: 1004 },
],
},
{
prop: 'completionCount',
label: '完成人数',
},
{ prop: 'fee', label: '费用(元)' },
{ prop: 'action', label: '操作', align: 'center', fixed: 'right', isShow: auths(['project:delete', 'project:edit', 'project:add']) },
]);
const isShowDialog = ref(false);
const dialogTitle = ref('新增');
const onOpenMenu = async (row) => {
console.log(row);
dialogTitle.value = row ? '编辑' : '新增';
formData.value = {
name: '',
projectTypeId: '',
completionCount: '',
fee: '',
durationMinutes: '0',
durationSeconds: '0',
groups: [
{
groupName: '',
birthDateStart: '',
birthDateEnd: '',
gender: '',
},
],
};
if (row) {
const { succeeded, data } = await projectDetailGet({ id: row.id });
formData.value = data;
}
isShowDialog.value = true;
};
//删除菜单
const onDeleteMenu = async (id) => {
const { succeeded, errors } = await merchantDeleteDelete({ id });
if (succeeded) {
ElMessage.success('删除成功');
} else {
ElMessage.error(errors);
}
};
// 表单提交
const onSubmit = () => {
if (!formRef.value) return;
formRef.value.validate(async (valid) => {
if (!valid) return;
try {
let res;
if (formData.value.id) {
res = await projectEditPut(formData.value);
} else {
res = await projectAddPost(formData.value);
}
if (res.succeeded) {
initParam.value.refresh = !initParam.value.refresh; // 刷新表格数据
ElMessage.success(dialogTitle.value + '成功');
isShowDialog.value = false;
} else {
ElMessage.error(res.errors);
}
} catch (error) {
console.error(error);
}
});
};
// 取消
const onCancel = () => {
isShowDialog.value = false;
};
</script>
<style scoped lang="scss">
.dialog-footer {
margin-top: 80px;
}
/* 时长组合框样式 */
.duration-row {
display: flex;
align-items: center;
gap: 8px;
}
.duration-row .el-input {
width: 120px;
}
.duration-separator {
color: #606266;
font-size: 14px;
}
.duration-label {
color: #909399;
font-size: 14px;
}
</style>