generated from Leo_Ding/web-template
Merge branch 'master' of https://gitlab.guxuan.icu/Leo_Ding/hahaPension_admin
This commit is contained in:
commit
9feb188430
3
.env.dev
3
.env.dev
@ -12,7 +12,8 @@ VITE_ROUTER_BASE=/
|
|||||||
VITE_ROUTER_HISTORY=hash
|
VITE_ROUTER_HISTORY=hash
|
||||||
|
|
||||||
# api
|
# api
|
||||||
VITE_API_BASIC='http://10.10.1.39:8040'
|
# VITE_API_BASIC='http://10.10.1.39:8040'
|
||||||
|
VITE_API_BASIC='http://115.239.217.220:8021'
|
||||||
VITE_API_UPLOAD='http://115.239.217.220:9458'
|
VITE_API_UPLOAD='http://115.239.217.220:9458'
|
||||||
VITE_API_HTTP=/api/v1/
|
VITE_API_HTTP=/api/v1/
|
||||||
# storage
|
# storage
|
||||||
|
|||||||
6825
package-lock.json
generated
6825
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -51,7 +51,7 @@
|
|||||||
"xy-storage": "^3.1.0"
|
"xy-storage": "^3.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^4.3.1",
|
"@vitejs/plugin-vue": "^5.0.0",
|
||||||
"eslint": "^8.47.0",
|
"eslint": "^8.47.0",
|
||||||
"eslint-config-prettier": "^9.0.0",
|
"eslint-config-prettier": "^9.0.0",
|
||||||
"eslint-plugin-prettier": "^5.0.0",
|
"eslint-plugin-prettier": "^5.0.0",
|
||||||
@ -60,7 +60,7 @@
|
|||||||
"less": "^4.2.0",
|
"less": "^4.2.0",
|
||||||
"lint-staged": "^14.0.0",
|
"lint-staged": "^14.0.0",
|
||||||
"rollup-plugin-visualizer": "^5.9.2",
|
"rollup-plugin-visualizer": "^5.9.2",
|
||||||
"vite": "^4.4.9",
|
"vite": "^5.0.0",
|
||||||
"vite-plugin-compression": "^0.5.1",
|
"vite-plugin-compression": "^0.5.1",
|
||||||
"vite-plugin-eslint": "^1.8.1",
|
"vite-plugin-eslint": "^1.8.1",
|
||||||
"vite-plugin-progress": "^0.0.7",
|
"vite-plugin-progress": "^0.0.7",
|
||||||
|
|||||||
@ -41,6 +41,7 @@ const theme = ref({
|
|||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
.bottom-center .amap-info-sharp:after {
|
.bottom-center .amap-info-sharp:after {
|
||||||
|
|
||||||
|
|||||||
@ -13,4 +13,12 @@ export const updateItem = (params) => request.basic.put(`/api/v1/service-people/
|
|||||||
// 删除数据
|
// 删除数据
|
||||||
export const delItem = (id) => request.basic.delete(`/api/v1/service-people/${id}`)
|
export const delItem = (id) => request.basic.delete(`/api/v1/service-people/${id}`)
|
||||||
|
|
||||||
|
//获取服务项目树状数据
|
||||||
|
export const getTreeData=(params)=>request.basic.get('/api/v1/service-projects/category_project',params)
|
||||||
|
|
||||||
|
//绑定服务项目
|
||||||
|
export const createProject=(params)=>request.basic.post('/api/v1/service-person-projects/many',params)
|
||||||
|
//获取服务人员绑定的服务项目
|
||||||
|
|
||||||
|
export const getProject=(params)=>request.basic.get('/api/v1/service-person-projects',params)
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,23 @@
|
|||||||
<!-- AreaCascader.vue -->
|
<!-- AreaCascader.vue -->
|
||||||
<template>
|
<template>
|
||||||
<a-cascader v-model:value="modelValue" :options="options" :load-data="loadData" :placeholder="placeholder"
|
<a-cascader v-model:value="innerValue" :options="options" :load-data="loadData" :placeholder="placeholder"
|
||||||
:style="style" :disabled="disabled" :show-search="showSearch" :allow-clear="allowClear"
|
:style="style" :disabled="disabled" :show-search="showSearch" :allow-clear="allowClear"
|
||||||
:change-on-select="changeOnSelect" :field-names="fieldNames" @change="handleChange" ref="cascaderRef" />
|
:change-on-select="changeOnSelect" :field-names="fieldNames" @change="handleChange" ref="cascaderRef" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch, nextTick, defineModel, onMounted,defineExpose } from 'vue';
|
import { ref, watch, nextTick, onMounted, defineProps, defineEmits, defineExpose } from 'vue';
|
||||||
import apis from '@/apis';
|
import apis from '@/apis';
|
||||||
import { useDicsStore } from '@/store';
|
import { useDicsStore } from '@/store';
|
||||||
|
|
||||||
const dicsStore = useDicsStore();
|
const dicsStore = useDicsStore();
|
||||||
const modelValue = defineModel();
|
|
||||||
|
// 🔸 使用 defineProps 接收 v-model 和其他 props
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
placeholder: { type: String, default: '请选择省市区' },
|
placeholder: { type: String, default: '请选择省市区' },
|
||||||
style: { type: Object, default: () => ({ width: '100%' }) },
|
style: { type: Object, default: () => ({ width: '100%' }) },
|
||||||
disabled: { type: Boolean, default: false },
|
disabled: { type: Boolean, default: false },
|
||||||
@ -23,26 +28,50 @@ const props = defineProps({
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({
|
default: () => ({
|
||||||
label: 'label',
|
label: 'label',
|
||||||
value: 'code',
|
value: 'code'
|
||||||
// children: 'children' // 注意:如果后端字段是 children,可以放开
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['change']);
|
// 🔸 显式定义 emit,支持 v-model 和 change 事件
|
||||||
const options = ref([]);
|
const emit = defineEmits(['update:modelValue', 'change']);
|
||||||
|
|
||||||
// 🔁 监听 store 的省份数据
|
// 🔸 内部响应式值,用于绑定 a-cascader 的 v-model:value
|
||||||
|
const innerValue = ref([]);
|
||||||
|
|
||||||
|
// 🔁 监听外部 modelValue 变化(用于回显)
|
||||||
watch(
|
watch(
|
||||||
() => dicsStore.provinceOptions,
|
() => props.modelValue,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
if (newVal && newVal.length > 0) {
|
if (newVal && typeof newVal === 'string') {
|
||||||
options.value = newVal;
|
const codes = newVal.split(',').filter(Boolean);
|
||||||
|
innerValue.value = codes;
|
||||||
|
// 如果 options 已加载,尝试初始化完整路径
|
||||||
|
if (options.value.length > 0 && codes.length > 1) {
|
||||||
|
initData(codes);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
innerValue.value = [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 🔁 监听 store 的省份数据
|
||||||
|
const options = ref([]);
|
||||||
|
watch(
|
||||||
|
() => dicsStore.provinceOptions,
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal && newVal.length > 0) {
|
||||||
|
options.value = newVal;
|
||||||
|
// 如果已有值,尝试初始化
|
||||||
|
if (innerValue.value.length > 1) {
|
||||||
|
initData([...innerValue.value]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
// 🔍 递归查找节点
|
// 🔍 递归查找节点
|
||||||
function findNodeInOptions(options, code) {
|
function findNodeInOptions(options, code) {
|
||||||
@ -55,37 +84,14 @@ function findNodeInOptions(options, code) {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
async function initData(codes){
|
|
||||||
// 从第二级开始,逐级模拟加载
|
|
||||||
for (let i = 1; i < codes.length; i++) {
|
|
||||||
const parentCode = codes[i - 1];
|
|
||||||
// const currentCode = val[i];
|
|
||||||
// 查找当前选中的父节点
|
|
||||||
let targetNode;
|
|
||||||
if (i === 1) {
|
|
||||||
// 第一级(省)在 options 中
|
|
||||||
targetNode = options.value.find(opt => opt.code === parentCode);
|
|
||||||
} else {
|
|
||||||
// 更深层级,需要递归查找
|
|
||||||
targetNode = findNodeInOptions(options.value, parentCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targetNode && !targetNode.children) {
|
|
||||||
// 触发 loadData 加载子级
|
|
||||||
await loadData([targetNode]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 等待加载完成
|
|
||||||
await nextTick();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 🌐 异步加载子节点
|
// 🌐 异步加载子节点
|
||||||
const loadData = async (selectedOptions) => {
|
const loadData = async (selectedOptions) => {
|
||||||
const targetOption = selectedOptions[selectedOptions.length - 1];
|
const targetOption = selectedOptions[selectedOptions.length - 1];
|
||||||
targetOption.loading = true;
|
targetOption.loading = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const parentId = targetOption.id || targetOption.code; // 兼容 id 或 code
|
const parentId = targetOption.id || targetOption.code;
|
||||||
const response = await apis.common.getAreaList({
|
const response = await apis.common.getAreaList({
|
||||||
current: 1,
|
current: 1,
|
||||||
pageSize: 100,
|
pageSize: 100,
|
||||||
@ -98,16 +104,15 @@ const loadData = async (selectedOptions) => {
|
|||||||
const children = response.data.map(item => ({
|
const children = response.data.map(item => ({
|
||||||
...item,
|
...item,
|
||||||
isLeaf: !item.hasChild,
|
isLeaf: !item.hasChild,
|
||||||
label: item.label || item.name, // 兼容字段
|
label: item.label || item.name,
|
||||||
value: item.code
|
value: item.code
|
||||||
}));
|
}));
|
||||||
|
|
||||||
targetOption.children = children;
|
targetOption.children = children;
|
||||||
} else {
|
} else {
|
||||||
targetOption.children = [];
|
targetOption.children = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 触发视图更新
|
// 触发更新
|
||||||
options.value = [...options.value];
|
options.value = [...options.value];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载子节点失败:', error);
|
console.error('加载子节点失败:', error);
|
||||||
@ -118,8 +123,38 @@ const loadData = async (selectedOptions) => {
|
|||||||
|
|
||||||
// 📣 处理选择变化
|
// 📣 处理选择变化
|
||||||
const handleChange = (value, selectedOptions) => {
|
const handleChange = (value, selectedOptions) => {
|
||||||
console.log(value)
|
// value 是 code 数组,如 ['110000', '110100', '110101']
|
||||||
|
const fullCode = value ? value.join(',') : '';
|
||||||
|
innerValue.value = value || [];
|
||||||
|
|
||||||
|
// 更新父组件的 v-model
|
||||||
|
emit('update:modelValue', fullCode);
|
||||||
|
// 触发 change 事件(传递 code 数组和 label 数组)
|
||||||
emit('change', value, selectedOptions?.map(opt => opt.label) || []);
|
emit('change', value, selectedOptions?.map(opt => opt.label) || []);
|
||||||
};
|
};
|
||||||
defineExpose({initData})
|
|
||||||
|
// 🧩 初始化已选路径(供父组件调用)
|
||||||
|
async function initData(codes) {
|
||||||
|
if (!codes || codes.length <= 1) return;
|
||||||
|
|
||||||
|
for (let i = 1; i < codes.length; i++) {
|
||||||
|
const parentCode = codes[i - 1];
|
||||||
|
let targetNode;
|
||||||
|
|
||||||
|
if (i === 1) {
|
||||||
|
targetNode = options.value.find(opt => opt.code === parentCode);
|
||||||
|
} else {
|
||||||
|
targetNode = findNodeInOptions(options.value, parentCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetNode && !targetNode.children) {
|
||||||
|
await loadData([targetNode]);
|
||||||
|
}
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 💡 暴露方法给父组件(如手动初始化)
|
||||||
|
defineExpose({ initData });
|
||||||
</script>
|
</script>
|
||||||
@ -126,7 +126,7 @@ const handleMapClick = (e) => {
|
|||||||
content: `<div style="padding:10px;min-width:200px;">
|
content: `<div style="padding:10px;min-width:200px;">
|
||||||
<div style="font-weight:bold;margin-bottom:5px;">点击位置</div>
|
<div style="font-weight:bold;margin-bottom:5px;">点击位置</div>
|
||||||
<div>${address}</div>
|
<div>${address}</div>
|
||||||
<div style="margin-top:8px;color:#666;">
|
<div style="margin-top:8px;color:#fff;">
|
||||||
<div>经度: ${lng.toFixed(6)}</div>
|
<div>经度: ${lng.toFixed(6)}</div>
|
||||||
<div>纬度: ${lat.toFixed(6)}</div>
|
<div>纬度: ${lat.toFixed(6)}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<!-- @/components/TreeSelect.vue -->
|
<!-- @/components/TreeSelect.vue -->
|
||||||
<template>
|
<template>
|
||||||
<a-tree-select v-model:value="modelValue" show-search :style="{ width: width }"
|
<a-tree-select v-model:value="innerValue" show-search :style="{ width: width }"
|
||||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" :placeholder="placeholder" :allow-clear="allowClear"
|
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" :placeholder="placeholder" :allow-clear="allowClear"
|
||||||
:tree-default-expand-all="defaultExpandAll" :tree-data="localTreeData" :tree-node-filter-prop="filterProp"
|
:tree-default-expand-all="defaultExpandAll" :tree-data="localTreeData" :tree-node-filter-prop="filterProp"
|
||||||
:disabled="disabled" :loading="loading" @change="handleChange" @search="handleSearch" @focus="handleFocus"
|
:disabled="disabled" :loading="loading" @change="handleChange" @search="handleSearch" @focus="handleFocus"
|
||||||
@ -10,11 +10,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch, onMounted,defineModel } from 'vue'
|
import { ref, watch, onMounted, defineProps, defineEmits } from 'vue';
|
||||||
import { useDicsStore } from '@/store'
|
import { useDicsStore } from '@/store';
|
||||||
const dicsStore = useDicsStore()
|
|
||||||
const modelValue = defineModel();
|
const dicsStore = useDicsStore();
|
||||||
|
|
||||||
|
// 🔸 定义 props(包含 v-model 的 modelValue)
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: [String, Number, Array], // 根据实际值类型调整,a-tree-select 可能是 string/array
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
allowClear: {
|
allowClear: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
@ -39,62 +45,75 @@ const props = defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
// 是否启用从 store 自动加载(可选)
|
|
||||||
useStore: {
|
useStore: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue', 'change', 'search', 'focus', 'blur'])
|
// 🔸 定义 emits
|
||||||
|
const emit = defineEmits(['update:modelValue', 'change', 'search', 'focus', 'blur']);
|
||||||
|
|
||||||
|
// 🔸 内部响应式值,用于绑定 a-tree-select 的 v-model:value
|
||||||
|
const innerValue = ref(props.modelValue);
|
||||||
|
|
||||||
const localTreeData = ref([])
|
// 🔁 监听外部 modelValue 变化(支持父组件动态更新值)
|
||||||
const loading = ref(false)
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(newVal) => {
|
||||||
|
innerValue.value = newVal;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 🔁 监听 store 数据变化
|
||||||
|
const localTreeData = ref([]);
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
// 监听 store 数据变化(响应式)
|
|
||||||
watch(
|
watch(
|
||||||
() => dicsStore.orgTree,
|
() => dicsStore.orgTree,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
if (newVal?.length > 0) {
|
if (Array.isArray(newVal) && newVal.length > 0) {
|
||||||
localTreeData.value = newVal
|
localTreeData.value = newVal;
|
||||||
console.log('localTreeData',localTreeData.value)
|
loading.value = false;
|
||||||
// modelValue.value=localTreeData.value[0].value
|
|
||||||
loading.value = false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
)
|
);
|
||||||
|
|
||||||
// 组件挂载时:如果启用了 store,且数据未加载,则主动加载
|
// 📥 组件挂载时自动加载(如果启用)
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
if (props.useStore) {
|
if (props.useStore) {
|
||||||
if (dicsStore.orgTree.length === 0 && !loading.value) {
|
if (dicsStore.orgTree.length === 0 && !loading.value) {
|
||||||
loading.value = true
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
await dicsStore.loadOrgTree()
|
await dicsStore.loadOrgTree();
|
||||||
// 数据会通过 watch 自动同步
|
// 数据会通过 watch 自动同步到 localTreeData
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
loading.value = false
|
console.error('加载组织树失败:', error);
|
||||||
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
|
// 📤 处理选择变更
|
||||||
const handleChange = (value, label, extra) => {
|
const handleChange = (value, label, extra) => {
|
||||||
emit('change', value, label, extra)
|
innerValue.value = value;
|
||||||
}
|
emit('update:modelValue', value); // 触发 v-model 更新
|
||||||
|
emit('change', value, label, extra);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 🔍 搜索
|
||||||
const handleSearch = (value) => {
|
const handleSearch = (value) => {
|
||||||
console.log(value)
|
emit('search', value);
|
||||||
emit('search', value)
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
// 💡 聚焦/失焦
|
||||||
const handleFocus = () => {
|
const handleFocus = () => {
|
||||||
emit('focus')
|
emit('focus');
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleBlur = () => {
|
const handleBlur = () => {
|
||||||
emit('blur')
|
emit('blur');
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
@ -7,23 +7,30 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref,defineModel } from 'vue'
|
import { ref, watch } from 'vue'
|
||||||
import apis from '@/apis'
|
import apis from '@/apis'
|
||||||
|
|
||||||
// 使用 defineModel 简化双向绑定
|
// 使用 defineModel 简化双向绑定
|
||||||
// 它会自动生成 { currentOrg: String, onUpdateCurrentOrg: Function }
|
// 它会自动生成 { currentOrg: String, onUpdateCurrentOrg: Function }
|
||||||
// 并返回一个可读写的 ref
|
// 并返回一个可读写的 ref
|
||||||
const model = defineModel('currentOrg', { type: String, default: '' })
|
const model = ref(props.currentOrg)
|
||||||
|
|
||||||
// 接收其他不需要双向绑定的 prop
|
// 接收其他不需要双向绑定的 prop
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
defaultOpen: {
|
defaultOpen: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
}
|
},
|
||||||
|
currentOrg: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
// 监听父组件 prop 变化(可选,如果父组件会动态改 currentOrg)
|
||||||
const emit = defineEmits(['change']) // 保留 change 事件
|
watch(() => props.currentOrg, (newVal) => {
|
||||||
|
model.value = newVal
|
||||||
|
})
|
||||||
|
const emit = defineEmits(['update:currentOrg', 'change']) // 保留 change 事件
|
||||||
|
|
||||||
// 获取数据
|
// 获取数据
|
||||||
const stationList = ref([])
|
const stationList = ref([])
|
||||||
@ -44,7 +51,8 @@ async function getData() {
|
|||||||
|
|
||||||
// 处理 change 事件
|
// 处理 change 事件
|
||||||
function handleChange(e) {
|
function handleChange(e) {
|
||||||
// model.value 会自动同步(不需要手动赋值)
|
model.value = e
|
||||||
|
emit('update:currentOrg', e) // 触发 v-model 更新
|
||||||
emit('change', e)
|
emit('change', e)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -1,12 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div class="brand" :class="cpClass" :style="cpStyle">
|
||||||
class="brand"
|
<!-- <img alt="" src="/public/logo-hahayun.png" /> -->
|
||||||
:class="cpClass"
|
<h1 style="color:#7babdb">{{ Title }}</h1>
|
||||||
:style="cpStyle">
|
|
||||||
<img
|
|
||||||
alt=""
|
|
||||||
:src="config('app.logo')" />
|
|
||||||
<h1>{{ config('app.title') }}</h1>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -15,7 +10,7 @@ import { storeToRefs } from 'pinia'
|
|||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { config } from '@/config'
|
import { config } from '@/config'
|
||||||
import { useAppStore } from '@/store'
|
import { useAppStore } from '@/store'
|
||||||
|
import storage from '@/utils/storage'
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'Brand',
|
name: 'Brand',
|
||||||
})
|
})
|
||||||
@ -49,6 +44,10 @@ const cpStyle = computed(() => {
|
|||||||
height: `${appConfig.value.headerHeight}px`,
|
height: `${appConfig.value.headerHeight}px`,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const Title = computed(() => {
|
||||||
|
const platForm = storage.local.getItem('platform')
|
||||||
|
return platForm == 'jianguan' ? '智慧养老居家监管平台' : platForm == 'yunying' ? '智慧养老居家运营平台' : '智慧养老居家呼叫平台'
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|||||||
@ -46,17 +46,17 @@ export default [
|
|||||||
permission: '*',
|
permission: '*',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
path: 'institution',
|
// path: 'institution',
|
||||||
name: 'institution',
|
// name: 'institution',
|
||||||
component: 'serverObj/institution/index.vue',
|
// component: 'serverObj/institution/index.vue',
|
||||||
meta: {
|
// meta: {
|
||||||
title: '机构服务对象列表',
|
// title: '机构服务对象列表',
|
||||||
isMenu: true,
|
// isMenu: true,
|
||||||
keepAlive: true,
|
// keepAlive: true,
|
||||||
permission: '*',
|
// permission: '*',
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
path: 'toBeInstitution',
|
path: 'toBeInstitution',
|
||||||
name: 'toBeInstitution',
|
name: 'toBeInstitution',
|
||||||
|
|||||||
@ -86,8 +86,7 @@
|
|||||||
<span v-else>女</span>
|
<span v-else>女</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.key === 'status'">
|
<template v-if="column.key === 'status'">
|
||||||
<a-tag v-if="record.status == '1'" color="green">启用</a-tag>
|
<a-tag>{{ dicsStore.getDictLabel('STAFF_STATUS', record.status) }}</a-tag>
|
||||||
<a-tag v-else color="red">禁用</a-tag>
|
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.key === 'serviceType'">
|
<template v-if="column.key === 'serviceType'">
|
||||||
<span>{{ dicsStore.getDictLabel('STAFF_TYPE', record.serviceType) }}</span>
|
<span>{{ dicsStore.getDictLabel('STAFF_TYPE', record.serviceType) }}</span>
|
||||||
@ -100,11 +99,13 @@
|
|||||||
<x-action-button @click="$refs.detailRef.handleEdit(record)">
|
<x-action-button @click="$refs.detailRef.handleEdit(record)">
|
||||||
<span>详情</span>
|
<span>详情</span>
|
||||||
</x-action-button>
|
</x-action-button>
|
||||||
<x-action-button @click="$refs.editDialogRef.handleEdit(record)" v-if="platForm==='yunying'">
|
<x-action-button @click="treeHandleEdit(record.id)" v-if="platForm === 'yunying'">
|
||||||
<span>服务项目</span>
|
<span>服务项目</span>
|
||||||
</x-action-button>
|
</x-action-button>
|
||||||
<x-action-button @click="$refs.editDialogRef.handleEdit(record)" v-if="platForm==='yunying'">
|
<x-action-button @click="handleStop(record)"
|
||||||
<span>停用</span>
|
v-if="platForm === 'yunying' && (record.status == '1' || record.status == '4')">
|
||||||
|
<span v-if="record.status === '1'">停用</span>
|
||||||
|
<span v-if="record.status === '4'">启用</span>
|
||||||
</x-action-button>
|
</x-action-button>
|
||||||
<x-action-button @click="handleDelete(record)">
|
<x-action-button @click="handleDelete(record)">
|
||||||
<span style="color: #ff4d4f;">删除</span>
|
<span style="color: #ff4d4f;">删除</span>
|
||||||
@ -117,6 +118,19 @@
|
|||||||
</a-row>
|
</a-row>
|
||||||
<edit-dialog ref="editDialogRef" @ok="onOk"></edit-dialog>
|
<edit-dialog ref="editDialogRef" @ok="onOk"></edit-dialog>
|
||||||
<detail ref="detailRef"></detail>
|
<detail ref="detailRef"></detail>
|
||||||
|
<a-modal v-model:open="treeOpen" title="绑定服务项目" @ok="handleOk">
|
||||||
|
<a-card>
|
||||||
|
<a-spin :spinning="spinning">
|
||||||
|
<a-tree v-model:expandedKeys="expandedKeys" v-model:selectedKeys="selectedKeys"
|
||||||
|
v-model:checkedKeys="checkedKeys" checkable :tree-data="treeData" @check="onCheck">
|
||||||
|
<template #title="{ title, key }">
|
||||||
|
<span v-if="key === '0-0-1-0'" style="color: #1890ff">{{ title }}</span>
|
||||||
|
<template v-else>{{ title }}</template>
|
||||||
|
</template>
|
||||||
|
</a-tree>
|
||||||
|
</a-spin>
|
||||||
|
</a-card>
|
||||||
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -133,9 +147,17 @@ import detail from './components/detail.vue'
|
|||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import NodeTree from '@/components/NodeTree/index.vue'
|
import NodeTree from '@/components/NodeTree/index.vue'
|
||||||
import storage from '@/utils/storage'
|
import storage from '@/utils/storage'
|
||||||
|
import { getBirthDate, spliceUrl } from '@/utils/util'
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'allocation',
|
name: 'allocation',
|
||||||
})
|
})
|
||||||
|
const currentId = ref('')
|
||||||
|
const spinning = ref(false)
|
||||||
|
const expandedKeys = ref([])
|
||||||
|
const selectedKeys = ref([])
|
||||||
|
const checkedKeys = ref([])
|
||||||
|
const treeData = ref([])
|
||||||
|
const treeOpen = ref(false)
|
||||||
const dicsStore = useDicsStore()
|
const dicsStore = useDicsStore()
|
||||||
const platForm = storage.local.getItem('platform')
|
const platForm = storage.local.getItem('platform')
|
||||||
const columns = [
|
const columns = [
|
||||||
@ -228,6 +250,7 @@ getPageList()
|
|||||||
|
|
||||||
async function getPageList() {
|
async function getPageList() {
|
||||||
try {
|
try {
|
||||||
|
loading.value = true
|
||||||
const { pageSize, current } = paginationState
|
const { pageSize, current } = paginationState
|
||||||
const { success, data, total } = await apis.serviceStaffList
|
const { success, data, total } = await apis.serviceStaffList
|
||||||
.getProjectList({
|
.getProjectList({
|
||||||
@ -244,32 +267,126 @@ async function getPageList() {
|
|||||||
if (config('http.code.success') === success) {
|
if (config('http.code.success') === success) {
|
||||||
listData.value = data
|
listData.value = data
|
||||||
paginationState.total = total
|
paginationState.total = total
|
||||||
|
loading.value = false
|
||||||
|
getServerProject()
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 判断是否为叶子节点
|
||||||
|
function isLeafNode(nodeKey, data = treeData.value) {
|
||||||
|
for (const item of data) {
|
||||||
|
if (item.key === nodeKey) {
|
||||||
|
return !item.children || item.children.length === 0;
|
||||||
|
}
|
||||||
|
if (item.children && item.children.length > 0) {
|
||||||
|
const found = isLeafNode(nodeKey, item.children);
|
||||||
|
if (found !== null) return found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null; // 未找到
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取所有叶子节点(递归)
|
||||||
|
function getAllLeafKeys(data) {
|
||||||
|
let leaves = [];
|
||||||
|
data.forEach(item => {
|
||||||
|
if (!item.children || item.children.length === 0) {
|
||||||
|
leaves.push(item.key);
|
||||||
|
} else {
|
||||||
|
leaves = leaves.concat(getAllLeafKeys(item.children));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return leaves;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理勾选
|
||||||
|
const onCheck = (checkedKeysObj, info) => {
|
||||||
|
console.log(checkedKeysObj)
|
||||||
|
// const { checked, halfChecked } = checkedKeysObj;
|
||||||
|
|
||||||
|
// 只保留叶子节点
|
||||||
|
const leafCheckedKeys = checkedKeysObj.filter(key => {
|
||||||
|
return isLeafNode(key) === true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新受控的 checkedKeys(可选:只显示叶子被选中)
|
||||||
|
checkedKeys.value = leafCheckedKeys;
|
||||||
|
};
|
||||||
|
/**核销 */
|
||||||
|
const getServerProject = async (id) => {
|
||||||
|
try {
|
||||||
|
currentId.value = id
|
||||||
|
const { data, success } = await apis.serviceStaffList.getTreeData({ categoryType: '1' })
|
||||||
|
if (success) {
|
||||||
|
treeData.value = transformCategories(data)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error.msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function treeHandleEdit(id){
|
||||||
|
try {
|
||||||
|
currentId.value=id
|
||||||
|
spinning.value=true
|
||||||
|
treeOpen.value = true
|
||||||
|
const {data,success}=await apis.serviceStaffList.getProject({current:1,pageSize:99,servicePersonId:id})
|
||||||
|
if (success) {
|
||||||
|
checkedKeys.value=data.map(item=>item.projectId)
|
||||||
|
console.log(selectedKeys.value)
|
||||||
|
}
|
||||||
|
spinning.value=false
|
||||||
|
} catch (error) {
|
||||||
|
spinning.value=false
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
function transformCategories(data) {
|
||||||
|
return data.map(category => ({
|
||||||
|
key: category.categoryId,
|
||||||
|
title: category.categoryName,
|
||||||
|
children: category.projects.map(project => ({
|
||||||
|
key: project.id,
|
||||||
|
title: project.name
|
||||||
|
}))
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
/**核销 */
|
const handleOk = async () => {
|
||||||
const checkHandler = (record) => {
|
try {
|
||||||
Modal.confirm({
|
const params = { servicePersonId: currentId.value, projectIds: checkedKeys.value }
|
||||||
title: '即将核销是否继续',
|
const {success} = await apis.serviceStaffList.createProject(params)
|
||||||
content: t('button.confirm'),
|
if(success){
|
||||||
okText: t('button.confirm'),
|
message.success('绑定成功')
|
||||||
onOk: async () => {
|
treeOpen.value=false
|
||||||
const params = {
|
checkedKeys.value=[]
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
const handleStop = async (record) => {
|
||||||
|
let params = {
|
||||||
...record,
|
...record,
|
||||||
status: 'success'
|
birthDay: record.birthDate2
|
||||||
}
|
}
|
||||||
const { success } = await apis.productOrder.updateItem(params.id, params).catch(() => {
|
|
||||||
// throw new Error()
|
if (record.laborContract && record.laborContract.length > 0) {
|
||||||
})
|
params.laborContractStartAt = record.laborContract[0]
|
||||||
if (config('http.code.success') === success) {
|
params.laborContractEndAt = record.laborContract[1]
|
||||||
// resolve()
|
|
||||||
message.success('核销成功')
|
|
||||||
await getPageList()
|
|
||||||
}
|
}
|
||||||
},
|
params.imgs = (record.imgs && record.imgs.length) > 0 ? record.imgs.map(item => spliceUrl(item)) : []
|
||||||
|
params.attachments = (record.attachments && record.attachments.length) > 0 ? record.attachments.map(item => spliceUrl(item)) : []
|
||||||
|
params.commissionRate = record.commissionRate ?? record.commissionRate / 100
|
||||||
|
params.status = record.status == '4' ? '1' : '4'
|
||||||
|
console.log(params)
|
||||||
|
const { success } = await apis.serviceStaffList.updateItem(params).catch(() => {
|
||||||
|
throw new Error()
|
||||||
})
|
})
|
||||||
|
if (success) {
|
||||||
|
getPageList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 删除
|
* 删除
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
<a-row :gutter="24">
|
<a-row :gutter="24">
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-form-item label="类型" name="categoryType" >
|
<a-form-item label="类型" name="categoryType" >
|
||||||
<a-select v-model:value="formData.categoryType" allowClear>
|
<a-select v-model:value="formData.categoryType" allowClear :disabled="categoryDisabled">
|
||||||
<a-select-option v-for="item in dicsStore.dictOptions.PROJECT_TYPE" :key="item.dval"
|
<a-select-option v-for="item in dicsStore.dictOptions.PROJECT_TYPE" :key="item.dval"
|
||||||
:value="item.dval">{{
|
:value="item.dval">{{
|
||||||
item.introduction }}</a-select-option>
|
item.introduction }}</a-select-option>
|
||||||
@ -138,6 +138,7 @@ const { modal, showModal, hideModal, showLoading, hideLoading } = useModal()
|
|||||||
const { formRecord, formData, formRef, formRules, resetForm } = useForm()
|
const { formRecord, formData, formRef, formRules, resetForm } = useForm()
|
||||||
const cancelText = ref('取消')
|
const cancelText = ref('取消')
|
||||||
const dicsStore = useDicsStore()
|
const dicsStore = useDicsStore()
|
||||||
|
const categoryDisabled=ref(false)
|
||||||
formRules.value = {
|
formRules.value = {
|
||||||
categoryType: [{ required: true, message: '请选择类型', trigger: ['blur', 'change'] }],
|
categoryType: [{ required: true, message: '请选择类型', trigger: ['blur', 'change'] }],
|
||||||
categoryId: [{ required: true, message: '请选择类型', trigger: ['blur', 'change'] }],
|
categoryId: [{ required: true, message: '请选择类型', trigger: ['blur', 'change'] }],
|
||||||
@ -158,6 +159,7 @@ function handleCreate() {
|
|||||||
type: 'create',
|
type: 'create',
|
||||||
title: '新增',
|
title: '新增',
|
||||||
})
|
})
|
||||||
|
categoryDisabled.value=false
|
||||||
formData.value = {
|
formData.value = {
|
||||||
priceUnit: '元/次',
|
priceUnit: '元/次',
|
||||||
frequencyUnit: '元/次',
|
frequencyUnit: '元/次',
|
||||||
@ -170,8 +172,9 @@ function handleCreate() {
|
|||||||
function handleEdit(record = {}) {
|
function handleEdit(record = {}) {
|
||||||
showModal({
|
showModal({
|
||||||
type: 'edit',
|
type: 'edit',
|
||||||
title: '编辑',
|
title: '编辑11',
|
||||||
})
|
})
|
||||||
|
categoryDisabled.value=true
|
||||||
formRecord.value = record
|
formRecord.value = record
|
||||||
formData.value = cloneDeep(record)
|
formData.value = cloneDeep(record)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
<a-col :span="6">
|
<a-col :span="6">
|
||||||
<a-form-item label="项目分类" name="categoryId">
|
<a-form-item label="项目分类" name="categoryId">
|
||||||
<a-select v-model:value="searchFormData.categoryId" allowClear>
|
<a-select v-model:value="searchFormData.categoryId" allowClear>
|
||||||
<a-select-option v-for="item in categoryList" :key="item.id" :value="item.name">{{
|
<a-select-option v-for="item in categoryList" :key="item.id" :value="item.id">{{
|
||||||
item.name }}</a-select-option>
|
item.name }}</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@ -50,7 +50,9 @@
|
|||||||
<template v-if="column.key === 'categoryType'">
|
<template v-if="column.key === 'categoryType'">
|
||||||
<span>{{ dicsStore.getDictLabel('PROJECT_TYPE', record.categoryType) }}</span>
|
<span>{{ dicsStore.getDictLabel('PROJECT_TYPE', record.categoryType) }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-if="column.key === 'categoryId'">
|
||||||
|
<span>{{categoryList.find(item=>item.id==record.categoryId).name}}</span>
|
||||||
|
</template>
|
||||||
<template v-if="column.key === 'price'">
|
<template v-if="column.key === 'price'">
|
||||||
<span>{{ record.price + record.frequencyUnit }}</span>
|
<span>{{ record.price + record.frequencyUnit }}</span>
|
||||||
</template>
|
</template>
|
||||||
@ -86,7 +88,7 @@ const categoryList=ref([])
|
|||||||
const columns = [
|
const columns = [
|
||||||
{ title: '序号', dataIndex: 'serialNumber', key: 'serialNumber', align: 'center', width: 80, },
|
{ title: '序号', dataIndex: 'serialNumber', key: 'serialNumber', align: 'center', width: 80, },
|
||||||
{ title: '类型', dataIndex: 'categoryType', key: 'categoryType', align: 'center', width: 100, },
|
{ title: '类型', dataIndex: 'categoryType', key: 'categoryType', align: 'center', width: 100, },
|
||||||
{ title: '分类名称', dataIndex: 'name', key: 'name', align: 'center', width: 180, },
|
{ title: '分类名称', dataIndex: 'categoryId', key: 'categoryId', align: 'center', width: 180, },
|
||||||
{ title: '项目名称', dataIndex: 'name', key: 'name', align: 'center', },
|
{ title: '项目名称', dataIndex: 'name', key: 'name', align: 'center', },
|
||||||
{ title: '价格', dataIndex: 'price', key: 'price', align: 'center', },
|
{ title: '价格', dataIndex: 'price', key: 'price', align: 'center', },
|
||||||
{ title: '简介', dataIndex: 'content', key: 'content', align: 'center', },
|
{ title: '简介', dataIndex: 'content', key: 'content', align: 'center', },
|
||||||
|
|||||||
@ -564,51 +564,54 @@ async function handleEdit(record = {}) {
|
|||||||
function isValidIdCard(value) {
|
function isValidIdCard(value) {
|
||||||
if (!value || typeof value !== 'string') return false;
|
if (!value || typeof value !== 'string') return false;
|
||||||
|
|
||||||
const idCardRegex = /(^\d{15}$)|(^\d{18}$)|(^\d{18}X$)/i;
|
// 清洗:去空格、转大写
|
||||||
if (!idCardRegex.test(value)) return false;
|
const id = value.trim().toUpperCase();
|
||||||
|
|
||||||
// 18位校验码验证
|
// 精确正则:15位纯数字,或18位(前17位数字 + 最后一位数字或X)
|
||||||
if (value.length === 18) {
|
const reg = /^(\d{15}|\d{17}[\dX])$/;
|
||||||
const Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1];
|
if (!reg.test(id)) return false;
|
||||||
const Vi = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
|
|
||||||
|
|
||||||
let sum = 0;
|
const len = id.length;
|
||||||
for (let i = 0; i < 17; i++) {
|
|
||||||
sum += parseInt(value[i], 10) * Wi[i];
|
|
||||||
}
|
|
||||||
const checkCode = Vi[sum % 11];
|
|
||||||
if (checkCode !== value[17].toUpperCase()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证生日
|
// 验证生日
|
||||||
let year, month, day;
|
let year, month, day;
|
||||||
if (value.length === 15) {
|
if (len === 15) {
|
||||||
year = '19' + value.substring(6, 8);
|
year = '19' + id.substring(6, 8);
|
||||||
month = value.substring(8, 10);
|
month = id.substring(8, 10);
|
||||||
day = value.substring(10, 12);
|
day = id.substring(10, 12);
|
||||||
} else {
|
} else {
|
||||||
year = value.substring(6, 10);
|
year = id.substring(6, 10);
|
||||||
month = value.substring(10, 12);
|
month = id.substring(10, 12);
|
||||||
day = value.substring(12, 14);
|
day = id.substring(12, 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
const date = new Date(year, month - 1, day);
|
const y = parseInt(year, 10);
|
||||||
if (
|
const m = parseInt(month, 10);
|
||||||
date.getFullYear() !== parseInt(year, 10) ||
|
const d = parseInt(day, 10);
|
||||||
date.getMonth() + 1 !== parseInt(month, 10) ||
|
const now = new Date();
|
||||||
date.getDate() !== parseInt(day, 10)
|
if (y < 1900 || y > now.getFullYear() || m < 1 || m > 12 || d < 1 || d > 31) {
|
||||||
) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentYear = new Date().getFullYear();
|
const date = new Date(y, m - 1, d);
|
||||||
const birthYear = parseInt(year, 10);
|
if (date.getFullYear() !== y || date.getMonth() + 1 !== m || date.getDate() !== d) {
|
||||||
if (birthYear < 1900 || birthYear > currentYear) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 18位校验码
|
||||||
|
if (len === 18) {
|
||||||
|
const Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
|
||||||
|
const Vi = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
|
||||||
|
let sum = 0;
|
||||||
|
for (let i = 0; i < 17; i++) {
|
||||||
|
sum += parseInt(id[i], 10) * Wi[i];
|
||||||
|
}
|
||||||
|
const checkCode = Vi[sum % 11];
|
||||||
|
if (checkCode !== id[17]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -633,6 +636,7 @@ function handleOk() {
|
|||||||
// params.stationId=storage.local.getItem('stationId')
|
// params.stationId=storage.local.getItem('stationId')
|
||||||
// 单独封装一个同步校验函数
|
// 单独封装一个同步校验函数
|
||||||
if (params.identityType === '1' && !isValidIdCard(params.identityNo)) {
|
if (params.identityType === '1' && !isValidIdCard(params.identityNo)) {
|
||||||
|
hideLoading()
|
||||||
return message.error('请输入正确的身份证号码')
|
return message.error('请输入正确的身份证号码')
|
||||||
}
|
}
|
||||||
let result = null
|
let result = null
|
||||||
|
|||||||
@ -106,6 +106,9 @@
|
|||||||
<template v-if="column.key === 'categoryType'">
|
<template v-if="column.key === 'categoryType'">
|
||||||
<span>{{ dicsStore.getDictLabel('PROJECT_TYPE', record.categoryType) }}</span>
|
<span>{{ dicsStore.getDictLabel('PROJECT_TYPE', record.categoryType) }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-if="column.key === 'categoryId'">
|
||||||
|
<span>{{categoryList.find(item=>item.id==record.categoryId).name}}</span>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
@ -117,7 +120,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed,nextTick } from 'vue'
|
||||||
import { config } from '@/config'
|
import { config } from '@/config'
|
||||||
import apis from '@/apis'
|
import apis from '@/apis'
|
||||||
import { useForm, useModal, usePagination } from '@/hooks'
|
import { useForm, useModal, usePagination } from '@/hooks'
|
||||||
@ -142,6 +145,7 @@ const mapVisible = ref(false)
|
|||||||
const stationList = ref([])
|
const stationList = ref([])
|
||||||
const spining = ref(false)
|
const spining = ref(false)
|
||||||
const areaCascaderRef=ref()
|
const areaCascaderRef=ref()
|
||||||
|
const categoryList = ref([])
|
||||||
formRules.value = {
|
formRules.value = {
|
||||||
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
||||||
identityType: [{ required: true, message: '请选择证件类型', trigger: 'change' }],
|
identityType: [{ required: true, message: '请选择证件类型', trigger: 'change' }],
|
||||||
@ -169,7 +173,7 @@ const serviceList = ref([])
|
|||||||
// 表格列定义
|
// 表格列定义
|
||||||
const columns = [
|
const columns = [
|
||||||
{ title: '类型', dataIndex: 'categoryType', key: 'categoryType', align: 'center', width: 100, },
|
{ title: '类型', dataIndex: 'categoryType', key: 'categoryType', align: 'center', width: 100, },
|
||||||
{ title: '分类名称', dataIndex: 'name', key: 'name', align: 'center', width: 180, },
|
{ title: '分类名称', dataIndex: 'categoryId', key: 'categoryId', align: 'center', width: 180, },
|
||||||
{ title: '项目名称', dataIndex: 'name', key: 'name', align: 'center', },
|
{ title: '项目名称', dataIndex: 'name', key: 'name', align: 'center', },
|
||||||
{ title: '价格', dataIndex: 'price', key: 'price', align: 'center', },
|
{ title: '价格', dataIndex: 'price', key: 'price', align: 'center', },
|
||||||
{ title: '简介', dataIndex: 'remark', key: 'remark', align: 'center', },
|
{ title: '简介', dataIndex: 'remark', key: 'remark', align: 'center', },
|
||||||
@ -190,6 +194,7 @@ const rowSelection = computed(() => ({
|
|||||||
}),
|
}),
|
||||||
}))
|
}))
|
||||||
getSeveicePeople()
|
getSeveicePeople()
|
||||||
|
getCategoriesAll()
|
||||||
async function getSeveicePeople() {
|
async function getSeveicePeople() {
|
||||||
try {
|
try {
|
||||||
const { success, data, total } = await apis.serviceStaffList
|
const { success, data, total } = await apis.serviceStaffList
|
||||||
@ -208,6 +213,21 @@ async function getSeveicePeople() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async function getCategoriesAll() {
|
||||||
|
try {
|
||||||
|
const { success, data, total } = await apis.projectType
|
||||||
|
.getProjectListAll({
|
||||||
|
pageSize: 100, current: 1,
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
throw new Error()
|
||||||
|
})
|
||||||
|
if (config('http.code.success') === success) {
|
||||||
|
categoryList.value = data.map(item => ({ id: item.id, name: item.name }))
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
}
|
||||||
|
}
|
||||||
function onAreaChange(value, labels) {
|
function onAreaChange(value, labels) {
|
||||||
formData.value.areaLabels = [...labels]
|
formData.value.areaLabels = [...labels]
|
||||||
}
|
}
|
||||||
@ -260,6 +280,7 @@ const handleRemove = (item) => {
|
|||||||
// 确认选择
|
// 确认选择
|
||||||
const handleConfirm = () => {
|
const handleConfirm = () => {
|
||||||
modalVisible.value = false
|
modalVisible.value = false
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 取消
|
// 取消
|
||||||
@ -299,6 +320,7 @@ async function handleEdit(record = {}, type) {
|
|||||||
})
|
})
|
||||||
if (type == '2') {
|
if (type == '2') {
|
||||||
formData.value.detailAddress = record.archive.homeDetailAddress
|
formData.value.detailAddress = record.archive.homeDetailAddress
|
||||||
|
console.log(record.archive.homeDetailAddress)
|
||||||
gps.value = record.region.join('') + record.archive.homeDetailAddress
|
gps.value = record.region.join('') + record.archive.homeDetailAddress
|
||||||
formData.value.lat = record.archive.lag
|
formData.value.lat = record.archive.lag
|
||||||
formData.value.lng = record.archive.lat
|
formData.value.lng = record.archive.lat
|
||||||
@ -307,6 +329,7 @@ async function handleEdit(record = {}, type) {
|
|||||||
getServiceStation()
|
getServiceStation()
|
||||||
spining.value = false
|
spining.value = false
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
spining.value = false
|
spining.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,7 +375,8 @@ function handleOk() {
|
|||||||
params.plannedServiceStartDate = formData.value.planeDate[0]
|
params.plannedServiceStartDate = formData.value.planeDate[0]
|
||||||
params.plannedEndDate = formData.value.planeDate[1]
|
params.plannedEndDate = formData.value.planeDate[1]
|
||||||
}
|
}
|
||||||
params.projects = serviceList.value
|
params.projects =selectedServices.value
|
||||||
|
console.log(params)
|
||||||
let result = null
|
let result = null
|
||||||
switch (modal.value.type) {
|
switch (modal.value.type) {
|
||||||
case 'create':
|
case 'create':
|
||||||
@ -389,6 +413,7 @@ function handleOk() {
|
|||||||
*/
|
*/
|
||||||
function handleCancel() {
|
function handleCancel() {
|
||||||
selectedServices.value = []
|
selectedServices.value = []
|
||||||
|
formData.value={}
|
||||||
hideModal()
|
hideModal()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -244,7 +244,8 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-button type="primary" v-if="platForm!=='hujiao'" @click="$refs.editDialogRef.handleCreate()">新建</a-button>
|
<a-button type="primary" v-if="platForm !== 'hujiao'"
|
||||||
|
@click="$refs.editDialogRef.handleCreate()">新建</a-button>
|
||||||
<a-dropdown v-if="platForm !== 'hujiao'">
|
<a-dropdown v-if="platForm !== 'hujiao'">
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
<a-menu @click="handleMenuClick">
|
<a-menu @click="handleMenuClick">
|
||||||
@ -325,7 +326,7 @@
|
|||||||
<x-action-button @click="$refs.detailRef.handleEdit(record)">
|
<x-action-button @click="$refs.detailRef.handleEdit(record)">
|
||||||
<span>详情</span>
|
<span>详情</span>
|
||||||
</x-action-button>
|
</x-action-button>
|
||||||
<x-action-button v-if="platForm==='yunying'">
|
<!-- <x-action-button v-if="platForm==='yunying'">
|
||||||
<a-dropdown>
|
<a-dropdown>
|
||||||
<a class="ant-dropdown-link" @click.prevent>
|
<a class="ant-dropdown-link" @click.prevent>
|
||||||
绑定
|
绑定
|
||||||
@ -342,14 +343,14 @@
|
|||||||
</a-menu>
|
</a-menu>
|
||||||
</template>
|
</template>
|
||||||
</a-dropdown>
|
</a-dropdown>
|
||||||
</x-action-button>
|
</x-action-button> -->
|
||||||
<x-action-button @click="$refs.lineOrderRef.handleEdit(record, '2')">
|
<x-action-button @click="$refs.lineOrderRef.handleEdit(record, '2')">
|
||||||
<span>线下工单</span>
|
<span>线下工单</span>
|
||||||
</x-action-button>
|
</x-action-button>
|
||||||
<x-action-button @click="$refs.lineOrderRef.handleEdit(record, '1')"
|
<!-- <x-action-button @click="$refs.lineOrderRef.handleEdit(record, '1')"
|
||||||
v-if="platForm !== 'yunying'">
|
v-if="platForm !== 'yunying'">
|
||||||
<span>线上工单</span>
|
<span>线上工单</span>
|
||||||
</x-action-button>
|
</x-action-button> -->
|
||||||
<x-action-button @click="$refs.transferRef.handleCreate(record.id, record.stationId)">
|
<x-action-button @click="$refs.transferRef.handleCreate(record.id, record.stationId)">
|
||||||
<span>转出</span>
|
<span>转出</span>
|
||||||
</x-action-button>
|
</x-action-button>
|
||||||
@ -475,20 +476,23 @@ const columns = [
|
|||||||
// --- 时间字段:去世时间 ---
|
// --- 时间字段:去世时间 ---
|
||||||
{
|
{
|
||||||
title: '去世时间',
|
title: '去世时间',
|
||||||
dataIndex: 'passWayAt',
|
dataIndex: 'livingStatus.passWayAt',
|
||||||
key: 'passWayAt',
|
key: 'livingStatus.passWayAt',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 140,
|
width: 140,
|
||||||
customRender: ({ text, record }) => {
|
customRender: ({ text, record }) => {
|
||||||
return text ? dayjs(text).format('YYYY-MM-DD') : '-';
|
return record.livingStatus.passWayAt ? dayjs(record.livingStatus.passWayAt).format('YYYY-MM-DD') : '-';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// --- 去世原因 ---
|
// --- 去世原因 ---
|
||||||
{
|
{
|
||||||
title: '去世原因',
|
title: '去世原因',
|
||||||
dataIndex: 'passWayReason',
|
dataIndex: 'livingStatus.passWayReason',
|
||||||
key: 'passWayReason',
|
key: 'livingStatus.passWayReason',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
customRender: ({ text, record }) => {
|
||||||
|
return record.livingStatus.passWayReason;
|
||||||
|
},
|
||||||
width: 140,
|
width: 140,
|
||||||
},
|
},
|
||||||
// --- 更新时间 ---
|
// --- 更新时间 ---
|
||||||
|
|||||||
@ -249,28 +249,7 @@ async function getPageList() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**核销 */
|
|
||||||
const checkHandler = (record) => {
|
|
||||||
Modal.confirm({
|
|
||||||
title: '即将核销是否继续',
|
|
||||||
content: t('button.confirm'),
|
|
||||||
okText: t('button.confirm'),
|
|
||||||
onOk: async () => {
|
|
||||||
const params = {
|
|
||||||
...record,
|
|
||||||
status: 'success'
|
|
||||||
}
|
|
||||||
const { success } = await apis.productOrder.updateItem(params.id, params).catch(() => {
|
|
||||||
// throw new Error()
|
|
||||||
})
|
|
||||||
if (config('http.code.success') === success) {
|
|
||||||
// resolve()
|
|
||||||
message.success('核销成功')
|
|
||||||
await getPageList()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 删除
|
* 删除
|
||||||
*/
|
*/
|
||||||
@ -283,7 +262,7 @@ function handleDelete({ id }) {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
; (async () => {
|
; (async () => {
|
||||||
try {
|
try {
|
||||||
const { success } = await apis.productOrder.delItem(id).catch(() => {
|
const { success } = await apis.serviceStaffList.delItem(id).catch(() => {
|
||||||
throw new Error()
|
throw new Error()
|
||||||
})
|
})
|
||||||
if (config('http.code.success') === success) {
|
if (config('http.code.success') === success) {
|
||||||
|
|||||||
@ -297,7 +297,7 @@
|
|||||||
<x-action-button @click="$refs.detailRef.handleCreate(record)">
|
<x-action-button @click="$refs.detailRef.handleCreate(record)">
|
||||||
<span>详情</span>
|
<span>详情</span>
|
||||||
</x-action-button>
|
</x-action-button>
|
||||||
<x-action-button v-if="platForm==='yunying'">
|
<!-- <x-action-button v-if="platForm==='yunying'">
|
||||||
<a-dropdown>
|
<a-dropdown>
|
||||||
<a class="ant-dropdown-link" @click.prevent>
|
<a class="ant-dropdown-link" @click.prevent>
|
||||||
绑定
|
绑定
|
||||||
@ -314,7 +314,7 @@
|
|||||||
</a-menu>
|
</a-menu>
|
||||||
</template>
|
</template>
|
||||||
</a-dropdown>
|
</a-dropdown>
|
||||||
</x-action-button>
|
</x-action-button> -->
|
||||||
<x-action-button @click="$refs.lineOrderRef.handleEdit(record, '2')">
|
<x-action-button @click="$refs.lineOrderRef.handleEdit(record, '2')">
|
||||||
<span>线下工单</span>
|
<span>线下工单</span>
|
||||||
</x-action-button>
|
</x-action-button>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user