From cf9a1f1585e5bda59a2ac39dd9fc23c237cf1f49 Mon Sep 17 00:00:00 2001 From: Zy <1448159279@qq.com> Date: Wed, 15 Apr 2026 17:32:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=B0=83=E6=9F=A5=E9=97=AE?= =?UTF-8?q?=E5=8D=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + src/api/system/Questionnaire/index.ts | 63 ++++ src/api/system/Questionnaire/type.ts | 161 +++++++++ src/api/system/repairProcess/index.ts | 63 ++++ src/api/system/repairProcess/type.ts | 125 +++++++ src/api/system/resident/type.ts | 8 +- src/components/Holder/index.vue | 130 +++++-- src/components/Holder/repairUser.vue | 19 +- src/permission.ts | 3 +- src/store/modules/user.ts | 6 +- src/utils/house.ts | 2 +- src/views/system/Activity/index.vue | 60 +++- src/views/system/Decoration/addDecoration.vue | 36 +- src/views/system/Decoration/index.vue | 74 +++- .../system/Questionnaire/addQuestionnaire.vue | 324 +++++++++++++++++ .../components/QuestionnaireEdit.vue | 330 ++++++++++++++++++ src/views/system/Questionnaire/index.vue | 251 +++++++++++++ src/views/system/Repair/addRepair.vue | 9 + src/views/system/Repair/repairMain.vue | 98 +++++- src/views/system/parking/addParking.vue | 2 +- src/views/system/test/Questionnaire.vue | 233 +++++++++++++ src/views/system/test/QuestionnaireEdit.vue | 311 +++++++++++++++++ src/views/system/test/api.ts | 44 +++ src/views/system/user/index.vue | 223 ++++-------- src/views/workbench/index.vue | 3 + 25 files changed, 2325 insertions(+), 254 deletions(-) create mode 100644 src/api/system/Questionnaire/index.ts create mode 100644 src/api/system/Questionnaire/type.ts create mode 100644 src/api/system/repairProcess/index.ts create mode 100644 src/api/system/repairProcess/type.ts create mode 100644 src/views/system/Questionnaire/addQuestionnaire.vue create mode 100644 src/views/system/Questionnaire/components/QuestionnaireEdit.vue create mode 100644 src/views/system/Questionnaire/index.vue create mode 100644 src/views/system/test/Questionnaire.vue create mode 100644 src/views/system/test/QuestionnaireEdit.vue create mode 100644 src/views/system/test/api.ts diff --git a/package.json b/package.json index 9894194..ec799bf 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "vue-json-pretty": "2.6.0", "vue-router": "5.0.3", "vue-types": "6.0.0", + "vuedraggable": "^4.1.0", "vxe-table": "4.18.1" }, "devDependencies": { diff --git a/src/api/system/Questionnaire/index.ts b/src/api/system/Questionnaire/index.ts new file mode 100644 index 0000000..d14135b --- /dev/null +++ b/src/api/system/Questionnaire/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { QuestionnaireVO, QuestionnaireForm, QuestionnaireQuery } from '@/api/system/Questionnaire/type'; + +/** + * 查询问卷调查列表 + * @param query + * @returns {*} + */ + +export const listQuestionnaire = (query?: QuestionnaireQuery): AxiosPromise => { + return request({ + url: '/questionnaire/list', + method: 'get', + params: query + }); +}; + +/** + * 查询问卷调查详细 + * @param id + */ +export const getQuestionnaire = (id: string | number): AxiosPromise => { + return request({ + url: '/questionnaire/' + id, + method: 'get' + }); +}; + +/** + * 新增问卷调查 + * @param data + */ +export const addQuestionnaire = (data: QuestionnaireForm) => { + return request({ + url: '/questionnaire', + method: 'post', + data: data + }); +}; + +/** + * 修改问卷调查 + * @param data + */ +export const updateQuestionnaire = (data: QuestionnaireForm) => { + return request({ + url: '/questionnaire', + method: 'put', + data: data + }); +}; + +/** + * 删除问卷调查 + * @param id + */ +export const delQuestionnaire = (id: string | number | Array) => { + return request({ + url: '/questionnaire/' + id, + method: 'delete' + }); +}; diff --git a/src/api/system/Questionnaire/type.ts b/src/api/system/Questionnaire/type.ts new file mode 100644 index 0000000..4796b98 --- /dev/null +++ b/src/api/system/Questionnaire/type.ts @@ -0,0 +1,161 @@ +export interface QuestionnaireVO { + /** + * 问卷ID + */ + id: string | number; + + /** + * 所属小区id + */ + villageId: string | number; + + /** + * 问卷标题 + */ + title: string; + + /** + * 问卷描述 + */ + description: string; + + /** + * 问卷题目结构(JSON数组) + */ + content: QuestionComponentItem[]; + + /** + * 状态:0-草稿 1-已发布 2-已结束 + */ + status: string; + + /** + * 参与范围 0全体业主 1部分业主 + */ + scope: string; + + /** + * 部分业主串 ”,“号隔开 + */ + residents: string | number; + + /** + * 备注 + */ + remark: string; +} + +export interface QuestionnaireForm extends BaseEntity { + /** + * 问卷ID + */ + id?: string | number; + + /** + * 所属小区id + */ + villageId?: string | number; + + /** + * 问卷标题 + */ + title?: string; + + /** + * 问卷描述 + */ + description?: string; + + /** + * 问卷题目结构(JSON数组) + */ + content?: string; + + /** + * 状态:0-草稿 1-已发布 2-已结束 + */ + status?: string; + + /** + * 参与范围 0全体业主 1部分业主 + */ + scope?: string; + + /** + * 部分业主串 ”,“号隔开 + */ + residents?: string; + + /** + * 备注 + */ + remark?: string; +} + +export interface QuestionnaireQuery extends PageQuery { + /** + * 所属小区id + */ + villageId?: string | number; + + /** + * 问卷标题 + */ + title?: string; + + /** + * 问卷描述 + */ + description?: string; + + /** + * 问卷题目结构(JSON数组) + */ + content?: string | QuestionComponentItem[]; + + /** + * 状态:0-草稿 1-已发布 2-已结束 + */ + status?: string; + + /** + * 参与范围 0全体业主 1部分业主 + */ + scope?: string; + + /** + * 部分业主串 ”,“号隔开 + */ + residents?: string | number; + + /** + * 日期范围参数 + */ + params?: any; +} + +// ==================== 调卷 类型定义 ==================== +export interface ComponentItem { + type: string; + label: string; + icon: any; +} + +export interface QuestionComponentOption { + label: string; +} + +export interface QuestionComponentItem { + cid: number; + type: string; + title: string; + required: boolean; + options: QuestionComponentOption[]; +} + +export interface QuestionComponentnaireForm { + id?: string | number | null; + title: string; + description: string; + content: QuestionComponentItem[]; +} diff --git a/src/api/system/repairProcess/index.ts b/src/api/system/repairProcess/index.ts new file mode 100644 index 0000000..2678b27 --- /dev/null +++ b/src/api/system/repairProcess/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { RepairProcessVO, RepairProcessForm, RepairProcessQuery } from '@/api/system/repairProcess/type'; + +/** + * 查询报修维修流程列表 + * @param query + * @returns {*} + */ + +export const listRepairProcess = (query?: RepairProcessQuery): AxiosPromise => { + return request({ + url: '/repairProcess/list', + method: 'get', + params: query + }); +}; + +/** + * 查询报修维修流程详细 + * @param id + */ +export const getRepairProcess = (id: string | number): AxiosPromise => { + return request({ + url: '/repairProcess/' + id, + method: 'get' + }); +}; + +/** + * 新增报修维修流程 + * @param data + */ +export const addRepairProcess = (data: RepairProcessForm) => { + return request({ + url: '/repairProcess', + method: 'post', + data: data + }); +}; + +/** + * 修改报修维修流程 + * @param data + */ +export const updateRepairProcess = (data: RepairProcessForm) => { + return request({ + url: '/repairProcess', + method: 'put', + data: data + }); +}; + +/** + * 删除报修维修流程 + * @param id + */ +export const delRepairProcess = (id: string | number | Array) => { + return request({ + url: '/repairProcess/' + id, + method: 'delete' + }); +}; diff --git a/src/api/system/repairProcess/type.ts b/src/api/system/repairProcess/type.ts new file mode 100644 index 0000000..f728035 --- /dev/null +++ b/src/api/system/repairProcess/type.ts @@ -0,0 +1,125 @@ +export interface RepairProcessVO { + /** + * 维修流程表id + */ + id: string; + + /** + * 所属报修id + */ + repairId: string; + + /** + * 提交时间 + */ + submitTime: string; + + /** + * 提交状态 0未提交 1已提交 + */ + submitStatus: string; + + /** + * 分配时间 + */ + allocateTime: string; + + /** + * 分配状态 0 待分配 1已分配 + */ + allocateStatus: string; + + /** + * 完成时间 + */ + completeTime: string; + + /** + * 完成状态 0进行中 1已完成 + */ + completeStatus: string; +} + +export interface RepairProcessForm extends BaseEntity { + /** + * 维修流程表id + */ + id?: string; + + /** + * 所属报修id + */ + repairId?: string; + + /** + * 提交时间 + */ + submitTime?: string; + + /** + * 提交状态 0未提交 1已提交 + */ + submitStatus?: string; + + /** + * 分配时间 + */ + allocateTime?: string; + + /** + * 分配状态 0 待分配 1已分配 + */ + allocateStatus?: string; + + /** + * 完成时间 + */ + completeTime?: string; + + /** + * 完成状态 0进行中 1已完成 + */ + completeStatus?: string; +} + +export interface RepairProcessQuery extends PageQuery { + /** + * 所属报修id + */ + repairId?: string | number; + + /** + * 提交时间 + */ + submitTime?: string; + + /** + * 提交状态 0未提交 1已提交 + */ + submitStatus?: string; + + /** + * 分配时间 + */ + allocateTime?: string; + + /** + * 分配状态 0 待分配 1已分配 + */ + allocateStatus?: string; + + /** + * 完成时间 + */ + completeTime?: string; + + /** + * 完成状态 0进行中 1已完成 + */ + completeStatus?: string; + + /** + * 日期范围参数 + */ + params?: any; +} diff --git a/src/api/system/resident/type.ts b/src/api/system/resident/type.ts index 96e0f6c..c88ce21 100644 --- a/src/api/system/resident/type.ts +++ b/src/api/system/resident/type.ts @@ -17,7 +17,7 @@ export interface ResidentVO { /** * 0业主 1租户 */ - type: number; + type: string; /** * 0 男性 1女性 @@ -92,7 +92,7 @@ export interface ResidentForm extends BaseEntity { /** * 0业主 1租户 */ - type?: number; + type?: string; /** * 0 男性 1女性 @@ -155,12 +155,12 @@ export interface ResidentQuery extends PageQuery { * 住户类型 * 0业主 1租户 */ - type: 0 | 1; + type: string; /** * 住户状态 * 0审核中 1 已认证 */ - status: 0 | 1; + status: string; houseId: number; villageId: number; diff --git a/src/components/Holder/index.vue b/src/components/Holder/index.vue index 3803e81..9f568f8 100644 --- a/src/components/Holder/index.vue +++ b/src/components/Holder/index.vue @@ -1,5 +1,7 @@ @@ -90,14 +92,24 @@ interface tableType extends ResidentVO { housePath?: string; } -const props = defineProps<{ - userid: string | number; -}>(); -const { userid } = toRefs(props); +// 触发方法 const emit = defineEmits<{ - change: [value: string | number]; + change: [value: string | number | (string | number)[]]; // 支持返回数组 }>(); +// ✅ 正确写法:分开定义,避免类型问题 +const props = defineProps<{ + userid: string | number | string[] | number[]; + isMultiple?: boolean; + returnvalue?: keyof tableType | '*'; +}>(); + +// ✅ 手动设置默认值(替代 withDefaults) +const isMultiple = computed(() => props.isMultiple ?? false); +const returnvalue = computed(() => props.returnvalue ?? 'userId'); // 👈 默认 userId + +const { userid } = toRefs(props); + const dialog = ref({ dialogVisible: false, dialogTitle: '选择住户' @@ -123,28 +135,65 @@ const total = ref(0); const loading = ref(false); // ============================================== -// 最佳单选方案:点击行选中,无报错、无循环、最稳定 +// ✅ 新增:处理 selection-change(多选专用) // ============================================== -function handleRowClick(row) { - multipleTableRef.value?.clearSelection(); - multipleTableRef.value?.toggleRowSelection(row, true); - multipleSelection.value = [row]; +function handleSelectionChange(selection: tableType[]) { + if (isMultiple.value) { + multipleSelection.value = selection; + } } // ============================================== -// 自动回显 userid +// 最佳单选方案:点击行选中,无报错、无循环、最稳定 +// ============================================== +function handleRowClick(row) { + if (isMultiple.value) { + // 多选:点击行切换选中状态 + const isSelected = multipleSelection.value.some((item) => item.id === row.id); + if (isSelected) { + multipleSelection.value = multipleSelection.value.filter((item) => item.id !== row.id); + multipleTableRef.value?.toggleRowSelection(row, false); + } else { + multipleSelection.value.push(row); + multipleTableRef.value?.toggleRowSelection(row, true); + } + } else { + // 单选:原有逻辑保持不变 + multipleTableRef.value?.clearSelection(); + multipleTableRef.value?.toggleRowSelection(row, true); + multipleSelection.value = [row]; + } +} + +// ============================================== +// ✅ 修改:支持多选回显 // ============================================== const handleUserSelection = () => { if (!userid.value || !tableData.value.length) return; - const findItem = tableData.value.find((item) => item.id == userid.value); - if (findItem) { - multipleSelection.value = [findItem]; - nextTick(() => { - multipleTableRef.value?.clearSelection(); - multipleTableRef.value?.toggleRowSelection(findItem, true); - }); - } + nextTick(() => { + multipleTableRef.value?.clearSelection(); + + if (isMultiple.value && Array.isArray(userid.value)) { + // 多选回显 + const selectedItems: tableType[] = []; + userid.value.forEach((id) => { + const findItem = tableData.value.find((item) => item.userId == id); + if (findItem) { + selectedItems.push(findItem); + multipleTableRef.value?.toggleRowSelection(findItem, true); + } + }); + multipleSelection.value = selectedItems; + } else { + // 单选回显(原有逻辑) + const findItem = tableData.value.find((item) => item.id == userid.value); + if (findItem) { + multipleSelection.value = [findItem]; + multipleTableRef.value?.toggleRowSelection(findItem, true); + } + } + }); }; watch(userid, handleUserSelection, { immediate: true }); @@ -178,7 +227,6 @@ function resetQuery() { pageSize: 10, ownerRelationship: '', // 👈 这里也改 name: '', - date: null, type: '', // 👈 这里也改 status: '', // 👈 这里也改 houseId: null, @@ -195,16 +243,44 @@ function conback() { resetQuery(); } -// 确定 -function confim() { +// ============================================== +// ✅ 核心修改:根据 returnvalue 返回对应的值 +// ============================================== +function confirm() { dialog.value.dialogVisible = false; if (multipleSelection.value.length > 0) { - emit('change', multipleSelection.value[0].id); + if (isMultiple.value) { + // 多选 + if (returnvalue.value === '*') { + // ✅ 返回整个对象数组 + emit('change', multipleSelection.value); + } else { + // 返回指定字段数组 + emit( + 'change', + multipleSelection.value.map((item) => item[returnvalue.value as keyof tableType]) + ); + } + } else { + // 单选 + if (returnvalue.value === '*') { + // ✅ 返回整个对象 + emit('change', multipleSelection.value[0]); + } else { + // 返回指定字段 + emit('change', multipleSelection.value[0][returnvalue.value as keyof tableType]); + } + } } } - // 初始化 getlist(); + +defineExpose({ + open: () => { + dialog.value.dialogVisible = true; + } +}); diff --git a/src/views/system/Questionnaire/components/QuestionnaireEdit.vue b/src/views/system/Questionnaire/components/QuestionnaireEdit.vue new file mode 100644 index 0000000..59f9f1c --- /dev/null +++ b/src/views/system/Questionnaire/components/QuestionnaireEdit.vue @@ -0,0 +1,330 @@ + + + + + diff --git a/src/views/system/Questionnaire/index.vue b/src/views/system/Questionnaire/index.vue new file mode 100644 index 0000000..03ce82f --- /dev/null +++ b/src/views/system/Questionnaire/index.vue @@ -0,0 +1,251 @@ + + + diff --git a/src/views/system/Repair/addRepair.vue b/src/views/system/Repair/addRepair.vue index ad9167c..b5b9f15 100644 --- a/src/views/system/Repair/addRepair.vue +++ b/src/views/system/Repair/addRepair.vue @@ -97,6 +97,7 @@ import { UploadProps, UploadUserFile } from 'element-plus'; import { addRepair, getRepair, updateRepair, uploadRepairImages } from '@/api/system/Repair'; import { gettreelistRepairProject } from '@/api/system/RepairProject'; import { useHouseStore } from '@/store/modules/house'; +import { validator } from '@/utils/Reg'; const houseStore = useHouseStore(); const { treedata } = storeToRefs(houseStore); @@ -125,6 +126,14 @@ const form = ref({ const rules = ref({ houseId: [{ required: true, message: '请选择关联房屋', trigger: 'blur' }], maintenanceItemId: [{ required: true, message: '请选择维修项目', trigger: 'blur' }], + phone: [ + { required: true, message: '请输入手机号', trigger: 'blur' }, + { + validator: (_, val) => validator(val, 'phone'), + message: '请输入正确的手机号码', + trigger: 'blur' + } + ], problem: [{ required: true, message: '请输入问题描述', trigger: 'blur' }] }); const userid = ref(null); diff --git a/src/views/system/Repair/repairMain.vue b/src/views/system/Repair/repairMain.vue index 9d0b7fa..1d251e4 100644 --- a/src/views/system/Repair/repairMain.vue +++ b/src/views/system/Repair/repairMain.vue @@ -94,11 +94,11 @@
维修师傅
- +
- 确定派单 - 返回 + 确定派单 + 返回
@@ -120,25 +120,24 @@ - + - + - + - @@ -152,22 +151,22 @@ import { ref } from 'vue'; import repairUser from '@/components/Holder/repairUser.vue'; import PageHeader from '@/components/Pageheader/index.vue'; -import { getRepair } from '@/api/system/Repair'; -import { getCommunitylistAPI } from '@/api/system/community'; -import { getVillageTree } from '@/api/system/house'; +import { getRepair, updateRepair } from '@/api/system/Repair'; import { convertBuildingToTree, getHousePathById } from '@/utils/house'; import { listRepairProject } from '@/api/system/RepairProject'; import { listResident } from '@/api/system/resident'; import { RepairVO } from '@/api/system/Repair/type'; import { useHouseStore } from '@/store/modules/house'; +import { listRepairProcess, updateRepairProcess } from '@/api/system/repairProcess'; const houseStore = useHouseStore(); const { treedata } = storeToRefs(houseStore); const route = useRoute(); const router = useRouter(); -const active = ref(6); -const activeStop = ref(4); + +const active = ref(0); +const activeStop = ref(0); interface formType extends RepairVO { maintenanceItem?: string; @@ -196,6 +195,17 @@ const userid = ref(); const projectlist = ref([]); // 住户 const residentList = ref([]); +// 审核流程 +const reviewInfo = ref({ + 'id': '', + 'repairId': '', + 'submitTime': '', + 'submitStatus': '0', + 'allocateTime': null, + 'allocateStatus': '0', + 'completeTime': null, + 'completeStatus': '0' +}); // ! 房屋 ==================================================================================================== async function init() { // 项目 @@ -217,15 +227,41 @@ async function init() { } } - const houseinfo = getHousePathById(treedata.value, Number(form.value.houseId), 'label'); - console.log(treedata.value); - + const houseinfo = getHousePathById(treedata.value, form.value.houseId, 'label'); + console.log(treedata.value, form.value.houseId, houseinfo); form.value.house = houseinfo.join(' - '); const residentinfo = residentList.value.find((item) => item.id === form.value.residentId); form.value.residentName = residentinfo.name; form.value.problemImageUrlList = form.value.problemImageUrl.split(',').filter((item) => item); + + // 获取保修审核状态 + const info = await listRepairProcess({ repairId: form.value.id, pageNum: 1, pageSize: 999999 }); + if (info && info.rows.length > 0) { + reviewInfo.value = info.rows.pop(); + handleReview(); + } +} + +// 处理审核 +function handleReview() { + if (reviewInfo.value.submitStatus === '1') { + // 提交完成 + active.value = 1; + activeStop.value = 1; + + if (reviewInfo.value.allocateStatus === '1') { + // 分配完成 + active.value = 2; + activeStop.value = 2; + // 维修完成 + if (reviewInfo.value.completeStatus === '1') { + active.value = 4; + activeStop.value = 4; + } + } + } } if (route.query.id) { @@ -233,6 +269,34 @@ if (route.query.id) { init(); } +/** 派单 */ +function handleSend() { + form.value.problemStatus = '1'; + updateRepair(form.value).then(() => { + reviewInfo.value.allocateTime = new Date().toLocaleString().replaceAll('/', '-'); + if (form.value.repairId) { + reviewInfo.value.allocateStatus = '1'; + } else { + reviewInfo.value.allocateStatus = '0'; + } + updateRepairProcess(reviewInfo.value).then(() => { + backRouter(); + }); + }); +} + +/** 选择维修人员 */ +function handleChange(row) { + form.value.repairId = row; +} + +/** 返回 */ +function backRouter() { + router.push({ + path: '/repair/repairlist' + }); +} + function handleEdit() { router.push({ path: '/repair/addRepair', diff --git a/src/views/system/parking/addParking.vue b/src/views/system/parking/addParking.vue index d765f27..58b0eb5 100644 --- a/src/views/system/parking/addParking.vue +++ b/src/views/system/parking/addParking.vue @@ -55,7 +55,7 @@ - + diff --git a/src/views/system/test/Questionnaire.vue b/src/views/system/test/Questionnaire.vue new file mode 100644 index 0000000..7dd8d16 --- /dev/null +++ b/src/views/system/test/Questionnaire.vue @@ -0,0 +1,233 @@ + + + + + diff --git a/src/views/system/test/QuestionnaireEdit.vue b/src/views/system/test/QuestionnaireEdit.vue new file mode 100644 index 0000000..c533df5 --- /dev/null +++ b/src/views/system/test/QuestionnaireEdit.vue @@ -0,0 +1,311 @@ + + + + + diff --git a/src/views/system/test/api.ts b/src/views/system/test/api.ts new file mode 100644 index 0000000..8974c4f --- /dev/null +++ b/src/views/system/test/api.ts @@ -0,0 +1,44 @@ +import request from '@/utils/request'; + +// 查询问卷列表 +export function listQuestionnaire(query) { + return request({ + url: '/questionnaire/list', + method: 'get', + params: query + }); +} + +// 查询问卷详细 +export function getQuestionnaire(id) { + return request({ + url: '/questionnaire/' + id, + method: 'get' + }); +} + +// 新增问卷 +export function addQuestionnaire(data) { + return request({ + url: '/questionnaire', + method: 'post', + data: data + }); +} + +// 修改问卷 +export function updateQuestionnaire(data) { + return request({ + url: '/questionnaire', + method: 'put', + data: data + }); +} + +// 删除问卷 +export function delQuestionnaire(id) { + return request({ + url: '/questionnaire/' + id, + method: 'delete' + }); +} diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue index da8c5bc..3f4dbfe 100644 --- a/src/views/system/user/index.vue +++ b/src/views/system/user/index.vue @@ -1,55 +1,25 @@ - + - + 将文件拖到此处,或点击上传