迁移人力资源、日常办公
This commit is contained in:
parent
6b60ac2cf9
commit
764e8f48bf
@ -6,6 +6,6 @@ VITE_NOW_TYPE = 'dist'
|
||||
# VITE_APP_BASE_URL='http://192.168.1.10:8546'
|
||||
# VITE_APP_BASE_URL='https://test-multi-store.lihaink.cn'
|
||||
# VITE_APP_BASE_URL='https://multi-store.lihaink.cn'
|
||||
VITE_APP_BASE_URL='http://192.168.1.22:8544'
|
||||
VITE_APP_BASE_URL='http://127.0.0.1:8544'
|
||||
# VITE_APP_BASE_URL='https://ceshi-multi-store.lihaink.cn'
|
||||
|
||||
|
69
src/api/article.ts
Normal file
69
src/api/article.ts
Normal file
@ -0,0 +1,69 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 文章分类列表
|
||||
export function articleCateLists(params ?: any) {
|
||||
return request.get({ url: '/article/articleCate/lists', params }, { urlPrefix: 'oa' })
|
||||
}
|
||||
// 文章分类列表
|
||||
export function articleCateAll(params ?: any) {
|
||||
return request.get({ url: '/article/articleCate/all', params }, { urlPrefix: 'oa' })
|
||||
}
|
||||
|
||||
// 添加文章分类
|
||||
export function articleCateAdd(params : any) {
|
||||
return request.post({ url: '/article/articleCate/add', params }, { urlPrefix: 'oa' })
|
||||
}
|
||||
|
||||
// 编辑文章分类
|
||||
export function articleCateEdit(params : any) {
|
||||
return request.post({ url: '/article/articleCate/edit', params }, { urlPrefix: 'oa' })
|
||||
}
|
||||
|
||||
// 删除文章分类
|
||||
export function articleCateDelete(params : any) {
|
||||
return request.post({ url: '/article/articleCate/delete', params }, { urlPrefix: 'oa' })
|
||||
}
|
||||
|
||||
// 文章分类详情
|
||||
export function articleCateDetail(params : any) {
|
||||
return request.get({ url: '/article/articleCate/detail', params }, { urlPrefix: 'oa' })
|
||||
}
|
||||
|
||||
// 文章分类状态
|
||||
export function articleCateStatus(params : any) {
|
||||
return request.post({ url: '/article/articleCate/updateStatus', params }, { urlPrefix: 'oa' })
|
||||
}
|
||||
|
||||
// 文章列表
|
||||
export function articleLists(params ?: any) {
|
||||
return request.get({ url: '/article/article/lists', params }, { urlPrefix: 'oa' })
|
||||
}
|
||||
// 文章列表
|
||||
export function articleAll(params ?: any) {
|
||||
return request.get({ url: '/article/all', params }, { urlPrefix: 'oa' })
|
||||
}
|
||||
|
||||
// 添加文章
|
||||
export function articleAdd(params : any) {
|
||||
return request.post({ url: '/article/article/add', params }, { urlPrefix: 'oa' })
|
||||
}
|
||||
|
||||
// 编辑文章
|
||||
export function articleEdit(params : any) {
|
||||
return request.post({ url: '/article/article/edit', params }, { urlPrefix: 'oa' })
|
||||
}
|
||||
|
||||
// 删除文章
|
||||
export function articleDelete(params : any) {
|
||||
return request.post({ url: '/article/article/delete', params }, { urlPrefix: 'oa' })
|
||||
}
|
||||
|
||||
// 文章详情
|
||||
export function articleDetail(params : any) {
|
||||
return request.get({ url: '/article/article/detail', params }, { urlPrefix: 'oa' })
|
||||
}
|
||||
|
||||
// 文章分类状态
|
||||
export function articleStatus(params : any) {
|
||||
return request.post({ url: '/article/article/updateStatus', params }, { urlPrefix: 'oa' })
|
||||
}
|
32
src/api/oa_department_change.ts
Normal file
32
src/api/oa_department_change.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
// 人事调动部门记录表列表
|
||||
export function apiOaDepartmentChangeLists(params : any) {
|
||||
return request.get({ url: "/works/hr/oaDepartmentChange/lists", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 添加人事调动部门记录表
|
||||
export function apiOaDepartmentChangeAdd(params : any) {
|
||||
return request.post({ url: "/works/hr/oaDepartmentChange/add", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 编辑人事调动部门记录表
|
||||
export function apiOaDepartmentChangeEdit(params : any) {
|
||||
return request.post({ url: "/works/hr/oaDepartmentChange/edit", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 删除人事调动部门记录表
|
||||
export function apiOaDepartmentChangeDelete(params : any) {
|
||||
return request.post({
|
||||
url: "/works/hr/oaDepartmentChange/delete",
|
||||
params,
|
||||
}, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 人事调动部门记录表详情
|
||||
export function apiOaDepartmentChangeDetail(params : any) {
|
||||
return request.get({
|
||||
url: "/works/hr/oaDepartmentChange/detail",
|
||||
params,
|
||||
}, { urlPrefix: 'oa' });
|
||||
}
|
26
src/api/oa_personal_quit.ts
Normal file
26
src/api/oa_personal_quit.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
// 人事离职记录表列表
|
||||
export function apiOaPersonalQuitLists(params : any) {
|
||||
return request.get({ url: "/works/hr/oaPersonalQuit/lists", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 添加人事离职记录表
|
||||
export function apiOaPersonalQuitAdd(params : any) {
|
||||
return request.post({ url: "/works/hr/oaPersonalQuit/add", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 编辑人事离职记录表
|
||||
export function apiOaPersonalQuitEdit(params : any) {
|
||||
return request.post({ url: "/works/hr/oaPersonalQuit/edit", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 删除人事离职记录表
|
||||
export function apiOaPersonalQuitDelete(params : any) {
|
||||
return request.post({ url: "/works/hr/oaPersonalQuit/delete", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 人事离职记录表详情
|
||||
export function apiOaPersonalQuitDetail(params : any) {
|
||||
return request.get({ url: "/works/hr/oaPersonalQuit/detail", params }, { urlPrefix: 'oa' });
|
||||
}
|
26
src/api/oa_plan.ts
Normal file
26
src/api/oa_plan.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
// 日程安排列表
|
||||
export function apiOaPlanLists(params : any) {
|
||||
return request.get({ url: "/works/rcbg/oaPlan/lists", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 添加日程安排
|
||||
export function apiOaPlanAdd(params : any) {
|
||||
return request.post({ url: "/works/rcbg/oaPlan/add", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 编辑日程安排
|
||||
export function apiOaPlanEdit(params : any) {
|
||||
return request.post({ url: "/works/rcbg/oaPlan/edit", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 删除日程安排
|
||||
export function apiOaPlanDelete(params : any) {
|
||||
return request.post({ url: "/works/rcbg/oaPlan/delete", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 日程安排详情
|
||||
export function apiOaPlanDetail(params : any) {
|
||||
return request.get({ url: "/works/rcbg/oaPlan/detail", params }, { urlPrefix: 'oa' });
|
||||
}
|
26
src/api/oa_schedule.ts
Normal file
26
src/api/oa_schedule.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
// 工作记录列表
|
||||
export function apiOaScheduleLists(params : any) {
|
||||
return request.get({ url: "/works/rcbg/oaSchedule/lists", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 添加工作记录
|
||||
export function apiOaScheduleAdd(params : any) {
|
||||
return request.post({ url: "/works/rcbg/oaSchedule/add", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 编辑工作记录
|
||||
export function apiOaScheduleEdit(params : any) {
|
||||
return request.post({ url: "/works/rcbg/oaSchedule/edit", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 删除工作记录
|
||||
export function apiOaScheduleDelete(params : any) {
|
||||
return request.post({ url: "/works/rcbg/oaSchedule/delete", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 工作记录详情
|
||||
export function apiOaScheduleDetail(params : any) {
|
||||
return request.get({ url: "/works/rcbg/oaSchedule/detail", params }, { urlPrefix: 'oa' });
|
||||
}
|
63
src/api/oa_work.ts
Normal file
63
src/api/oa_work.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
// 汇报工作表列表
|
||||
export function apiOaWorkLists(params : any) {
|
||||
return request.get({ url: "/works/rcbg/oaWork/lists", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 添加汇报工作表
|
||||
export function apiOaWorkAdd(params : any) {
|
||||
return request.post({ url: "/works/rcbg/oaWork/add", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 编辑汇报工作表
|
||||
export function apiOaWorkEdit(params : any) {
|
||||
return request.post({ url: "/works/rcbg/oaWork/edit", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 删除汇报工作表
|
||||
export function apiOaWorkDelete(params : any) {
|
||||
return request.post({ url: "/works/rcbg/oaWork/delete", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 汇报工作表详情
|
||||
export function apiOaWorkDetail(params : any) {
|
||||
return request.get({ url: "/works/rcbg/oaWork/detail", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 汇报工作表列表
|
||||
export function apiOaWorkrecordLists(params : any) {
|
||||
return request.get({ url: "/works/rcbg/oaWorkRecord/lists", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 汇报工作表详情
|
||||
export function apiOaWorkrecordDetail(params : any) {
|
||||
return request.get({ url: "/works/rcbg/oaWorkRecord/detail", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
// 删除汇报工作表
|
||||
export function apiOaWorkrecordDelete(params : any) {
|
||||
return request.post({ url: "/works/rcbg/oaWorkRecord/delete", params }, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 汇报工作表列表
|
||||
export function apiOaWorkrcommentLists(params : any) {
|
||||
return request.get({
|
||||
url: "/works/rcbg/oaWorkComment/lists",
|
||||
params,
|
||||
}, { urlPrefix: 'oa' });
|
||||
}
|
||||
|
||||
// 汇报工作表列表
|
||||
export function apiOaWorkrcommentAdd(params : any) {
|
||||
return request.post({
|
||||
url: "/works/rcbg/oaWorkComment/add",
|
||||
params,
|
||||
}, { urlPrefix: 'oa' });
|
||||
}
|
||||
// 汇报工作表列表
|
||||
export function apiOaWorkrcommentDelete(params : any) {
|
||||
return request.post({
|
||||
url: "/works/rcbg/oaWorkComment/delete",
|
||||
params,
|
||||
}, { urlPrefix: 'oa' });
|
||||
}
|
32
src/api/org/organization.ts
Normal file
32
src/api/org/organization.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 组织列表
|
||||
export function orgsLists(params?: any) {
|
||||
return request.get({ url: '/dept.orgs/lists', params })
|
||||
}
|
||||
|
||||
// 添加组织
|
||||
export function orgsAdd(params: any) {
|
||||
return request.post({ url: '/dept.orgs/add', params })
|
||||
}
|
||||
|
||||
// 编辑组织
|
||||
export function orgsEdit(params: any) {
|
||||
return request.post({ url: '/dept.orgs/edit', params })
|
||||
}
|
||||
|
||||
// 删除组织
|
||||
export function orgsDelete(params: any) {
|
||||
return request.post({ url: '/dept.orgs/delete', params })
|
||||
}
|
||||
|
||||
// 组织详情
|
||||
export function orgsDetail(params: any) {
|
||||
return request.get({ url: '/dept.orgs/detail', params })
|
||||
}
|
||||
|
||||
|
||||
// 所有组织
|
||||
export function getAll() {
|
||||
return request.get({ url: '/dept.orgs/getAll'})
|
||||
}
|
16
src/components/annexLink/index.vue
Normal file
16
src/components/annexLink/index.vue
Normal file
@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<el-link type="primary" v-for="(item, index) in annex" :key="index" :href="item.uri" target="_blank" class="mr-5">{{
|
||||
item.name
|
||||
}}</el-link>
|
||||
<span v-if="!annex.length">暂无附件</span>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { defineProps } from 'vue'
|
||||
|
||||
defineProps({
|
||||
annex: Array
|
||||
})
|
||||
|
||||
|
||||
|
||||
</script>
|
93
src/views/article/column/edit.vue
Normal file
93
src/views/article/column/edit.vue
Normal file
@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<div class="edit-popup">
|
||||
<popup
|
||||
ref="popupRef"
|
||||
:title="popupTitle"
|
||||
:async="true"
|
||||
width="550px"
|
||||
@confirm="handleSubmit"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form ref="formRef" :model="formData" label-width="84px" :rules="formRules">
|
||||
<el-form-item label="栏目名称" prop="name">
|
||||
<el-input v-model="formData.name" placeholder="请输入栏目名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<div>
|
||||
<el-input-number v-model="formData.sort" :min="0" :max="9999" />
|
||||
<div class="form-tips">默认为0, 数值越大越排前</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="is_show">
|
||||
<el-switch v-model="formData.is_show" :active-value="1" :inactive-value="0" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</popup>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { articleCateEdit, articleCateAdd, articleCateDetail } from '@/api/article'
|
||||
import Popup from '@/components/popup/index.vue'
|
||||
const emit = defineEmits(['success', 'close'])
|
||||
const formRef = shallowRef<FormInstance>()
|
||||
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||
const mode = ref('add')
|
||||
const popupTitle = computed(() => {
|
||||
return mode.value == 'edit' ? '编辑栏目' : '新增栏目'
|
||||
})
|
||||
const formData = reactive({
|
||||
id: '',
|
||||
name: '',
|
||||
sort: 0,
|
||||
is_show: 1
|
||||
})
|
||||
|
||||
const formRules = {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入栏目名称',
|
||||
trigger: ['blur']
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
await formRef.value?.validate()
|
||||
mode.value == 'edit' ? await articleCateEdit(formData) : await articleCateAdd(formData)
|
||||
popupRef.value?.close()
|
||||
emit('success')
|
||||
}
|
||||
|
||||
const open = (type = 'add') => {
|
||||
mode.value = type
|
||||
popupRef.value?.open()
|
||||
}
|
||||
|
||||
const setFormData = (data: Record<any, any>) => {
|
||||
for (const key in formData) {
|
||||
if (data[key] != null && data[key] != undefined) {
|
||||
//@ts-ignore
|
||||
formData[key] = data[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getDetail = async (row: Record<string, any>) => {
|
||||
const data = await articleCateDetail({
|
||||
id: row.id
|
||||
})
|
||||
setFormData(data)
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
setFormData,
|
||||
getDetail
|
||||
})
|
||||
</script>
|
108
src/views/article/column/index.vue
Normal file
108
src/views/article/column/index.vue
Normal file
@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-card class="!border-none" shadow="never">
|
||||
<el-alert
|
||||
type="warning"
|
||||
title="温馨提示:用于管理网站的分类,只可添加到一级"
|
||||
:closable="false"
|
||||
show-icon
|
||||
/>
|
||||
</el-card>
|
||||
<el-card class="!border-none mt-4" shadow="never" v-loading="pager.loading">
|
||||
<div>
|
||||
<el-button
|
||||
class="mb-4"
|
||||
v-perms="['article.articleCate/add']"
|
||||
type="primary"
|
||||
@click="handleAdd()"
|
||||
>
|
||||
<template #icon>
|
||||
<icon name="el-icon-Plus" />
|
||||
</template>
|
||||
新增
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table size="large" :data="pager.lists">
|
||||
<el-table-column label="栏目名称" prop="name" min-width="120" />
|
||||
<el-table-column label="文章数" prop="article_count" min-width="120" />
|
||||
<el-table-column label="状态" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<el-switch
|
||||
v-perms="['article.articleCate/updateStatus']"
|
||||
v-model="row.is_show"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
@change="changeStatus($event, row.id)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="排序" prop="sort" min-width="120" />
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
v-perms="['article.articleCate/edit']"
|
||||
type="primary"
|
||||
link
|
||||
@click="handleEdit(row)"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
v-perms="['article.articleCate/delete']"
|
||||
type="danger"
|
||||
link
|
||||
@click="handleDelete(row.id)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="flex justify-end mt-4">
|
||||
<pagination v-model="pager" @change="getLists" />
|
||||
</div>
|
||||
</el-card>
|
||||
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="articleColumn">
|
||||
import { articleCateDelete, articleCateLists, articleCateStatus } from '@/api/article'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import feedback from '@/utils/feedback'
|
||||
import EditPopup from './edit.vue'
|
||||
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
|
||||
const showEdit = ref(false)
|
||||
|
||||
const { pager, getLists } = usePaging({
|
||||
fetchFun: articleCateLists
|
||||
})
|
||||
const handleAdd = async () => {
|
||||
showEdit.value = true
|
||||
await nextTick()
|
||||
editRef.value?.open('add')
|
||||
}
|
||||
|
||||
const handleEdit = async (data: any) => {
|
||||
showEdit.value = true
|
||||
await nextTick()
|
||||
editRef.value?.open('edit')
|
||||
editRef.value?.getDetail(data)
|
||||
}
|
||||
|
||||
const handleDelete = async (id: number) => {
|
||||
await feedback.confirm('确定要删除?')
|
||||
await articleCateDelete({ id })
|
||||
getLists()
|
||||
}
|
||||
|
||||
const changeStatus = async (is_show: any, id: number) => {
|
||||
try {
|
||||
await articleCateStatus({ id, is_show })
|
||||
getLists()
|
||||
} catch (error) {
|
||||
getLists()
|
||||
}
|
||||
}
|
||||
|
||||
getLists()
|
||||
</script>
|
65
src/views/article/lists/detail.vue
Normal file
65
src/views/article/lists/detail.vue
Normal file
@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<div class="detail-popup">
|
||||
<popup ref="popupRef" title="文章详情" :async="true" width="60vw" @confirm="handleSubmit" @close="handleClose">
|
||||
<h1 style="font-size:32px; margin-bottom: 20px;font-weight:700"> {{ formData.title }} </h1>
|
||||
<h4 style="margin:20px 0"> {{ formData.desc }} </h4>
|
||||
<el-image :src="formData.image" />
|
||||
<div v-html="formData.content"> </div>
|
||||
<div style="text-align: right;margin-top: 20px">
|
||||
本文由{{ formData.author }}于{{ (formData.create_time) }}发布
|
||||
</div>
|
||||
<!-- {{ formData }} -->
|
||||
</popup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="customdetail">
|
||||
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import Popup from '@/components/popup/index.vue'
|
||||
import { timeFormat } from '@/utils/util'
|
||||
import type { PropType } from 'vue'
|
||||
|
||||
const emit = defineEmits(['success', 'close'])
|
||||
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||
|
||||
|
||||
// 表单数据
|
||||
const formData = ref({
|
||||
|
||||
})
|
||||
|
||||
|
||||
// 提交按钮
|
||||
const handleSubmit = async () => {
|
||||
popupRef.value?.close()
|
||||
|
||||
}
|
||||
|
||||
//打开弹窗
|
||||
const open = (data) => {
|
||||
popupRef.value?.open()
|
||||
formData.value = data
|
||||
}
|
||||
|
||||
// 关闭回调
|
||||
const handleClose = () => {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tit {
|
||||
font-size: 1.2em;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
:deep(.my-label) {
|
||||
width: 150px;
|
||||
}
|
||||
</style>
|
173
src/views/article/lists/edit.vue
Normal file
173
src/views/article/lists/edit.vue
Normal file
@ -0,0 +1,173 @@
|
||||
<template>
|
||||
<div class="article-edit">
|
||||
<el-card class="!border-none" shadow="never">
|
||||
<el-page-header :content="$route.meta.title" @back="$router.back()" />
|
||||
</el-card>
|
||||
<el-card class="mt-4 !border-none" shadow="never">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
class="ls-form"
|
||||
:model="formData"
|
||||
label-width="85px"
|
||||
:rules="rules"
|
||||
>
|
||||
<div class="xl:flex">
|
||||
<div>
|
||||
<el-form-item label="文章标题" prop="title">
|
||||
<div class="w-80">
|
||||
<el-input
|
||||
v-model="formData.title"
|
||||
placeholder="请输入文章标题"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 3, maxRows: 3 }"
|
||||
maxlength="64"
|
||||
show-word-limit
|
||||
clearable
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="文章栏目" prop="cid">
|
||||
<el-select
|
||||
class="w-80"
|
||||
v-model="formData.cid"
|
||||
placeholder="请选择文章栏目"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in optionsData.article_cate"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="文章简介" prop="desc">
|
||||
<div class="w-80">
|
||||
<el-input
|
||||
v-model="formData.desc"
|
||||
placeholder="请输入文章简介"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 3, maxRows: 6 }"
|
||||
:maxlength="200"
|
||||
show-word-limit
|
||||
clearable
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="摘要" prop="abstract">
|
||||
<div class="w-80">
|
||||
<el-input
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 6, maxRows: 6 }"
|
||||
v-model="formData.abstract"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
clearable
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="文章封面" prop="image">
|
||||
<div>
|
||||
<div>
|
||||
<material-picker v-model="formData.image" :limit="1" />
|
||||
</div>
|
||||
<div class="form-tips">建议尺寸:240*180px</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="作者" prop="author">
|
||||
<div class="w-80">
|
||||
<el-input v-model="formData.author" placeholder="请输入作者名称" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<div>
|
||||
<el-input-number v-model="formData.sort" :min="0" :max="9999" />
|
||||
<div class="form-tips">默认为0, 数值越大越排前</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="初始浏览量" prop="click_virtual">
|
||||
<div>
|
||||
<el-input-number v-model="formData.click_virtual" :min="0" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="文章状态" required prop="is_show">
|
||||
<el-radio-group v-model="formData.is_show">
|
||||
<el-radio :label="1">显示</el-radio>
|
||||
<el-radio :label="0">隐藏</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="xl:ml-20">
|
||||
<el-form-item label="文章内容" prop="content">
|
||||
<editor v-model="formData.content" :height="667" :width="375" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<footer-btns>
|
||||
<el-button type="primary" @click="handleSave">保存</el-button>
|
||||
</footer-btns>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="articleListsEdit">
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { useDictOptions } from '@/hooks/useDictOptions'
|
||||
import { articleDetail, articleEdit, articleAdd, articleCateAll } from '@/api/article'
|
||||
import useMultipleTabs from '@/hooks/useMultipleTabs'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const formData = reactive({
|
||||
id: '',
|
||||
title: '',
|
||||
image: '',
|
||||
cid: '',
|
||||
desc: '',
|
||||
author: '',
|
||||
content: '',
|
||||
click_virtual: 0,
|
||||
sort: 0,
|
||||
is_show: 1,
|
||||
abstract: ''
|
||||
})
|
||||
|
||||
const { removeTab } = useMultipleTabs()
|
||||
const formRef = shallowRef<FormInstance>()
|
||||
const rules = reactive({
|
||||
title: [{ required: true, message: '请输入文章标题', trigger: 'blur' }],
|
||||
cid: [{ required: true, message: '请选择文章栏目', trigger: 'blur' }]
|
||||
})
|
||||
|
||||
const getDetails = async () => {
|
||||
const data = await articleDetail({
|
||||
id: route.query.id
|
||||
})
|
||||
Object.keys(formData).forEach((key) => {
|
||||
//@ts-ignore
|
||||
formData[key] = data[key]
|
||||
})
|
||||
}
|
||||
|
||||
const { optionsData } = useDictOptions<{
|
||||
article_cate: any[]
|
||||
}>({
|
||||
article_cate: {
|
||||
api: articleCateAll
|
||||
}
|
||||
})
|
||||
|
||||
const handleSave = async () => {
|
||||
await formRef.value?.validate()
|
||||
if (route.query.id) {
|
||||
await articleEdit(formData)
|
||||
} else {
|
||||
await articleAdd(formData)
|
||||
}
|
||||
removeTab()
|
||||
router.back()
|
||||
}
|
||||
|
||||
route.query.id && getDetails()
|
||||
</script>
|
154
src/views/article/lists/index.vue
Normal file
154
src/views/article/lists/index.vue
Normal file
@ -0,0 +1,154 @@
|
||||
<template>
|
||||
<div class="article-lists">
|
||||
<el-card class="!border-none" shadow="never">
|
||||
<el-form ref="formRef" class="mb-[-16px]" :model="queryParams" :inline="true">
|
||||
<el-form-item label="文章标题">
|
||||
<el-input class="w-[280px]" v-model="queryParams.title" clearable @keyup.enter="resetPage" />
|
||||
</el-form-item>
|
||||
<el-form-item label="栏目名称">
|
||||
<el-select class="w-[280px]" v-model="queryParams.cid">
|
||||
<el-option label="全部" value />
|
||||
<el-option v-for="item in optionsData.article_cate" :key="item.id" :label="item.name"
|
||||
:value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="文章状态">
|
||||
<el-select class="w-[280px]" v-model="queryParams.is_show">
|
||||
<el-option label="全部" value />
|
||||
<el-option label="显示" :value="1" />
|
||||
<el-option label="隐藏" :value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="resetPage">查询</el-button>
|
||||
<el-button @click="resetParams">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-card class="!border-none mt-4" shadow="never">
|
||||
<div>
|
||||
<router-link v-perms="['article.article/add', 'article.article/add:edit']" :to="{
|
||||
path: getRoutePath('article.article/add:edit')
|
||||
}">
|
||||
<el-button type="primary" class="mb-4">
|
||||
<template #icon>
|
||||
<icon name="el-icon-Plus" />
|
||||
</template>
|
||||
发布文章
|
||||
</el-button>
|
||||
</router-link>
|
||||
</div>
|
||||
<el-table size="large" v-loading="pager.loading" :data="pager.lists">
|
||||
<el-table-column label="ID" prop="id" min-width="80" />
|
||||
<el-table-column label="封面" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<image-contain v-if="row.image" :src="row.image" :width="60" :height="45"
|
||||
:preview-src-list="[row.image]" preview-teleported fit="contain" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="标题" prop="title" min-width="160" show-tooltip-when-overflow />
|
||||
<el-table-column label="栏目" prop="cate_name" min-width="100" />
|
||||
<el-table-column label="作者" prop="author" min-width="120" />
|
||||
<el-table-column label="浏览量" prop="click" min-width="100" />
|
||||
<el-table-column label="状态" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<el-switch v-perms="['article.article/updateStatus']" v-model="row.is_show" :active-value="1"
|
||||
:inactive-value="0" @change="changeStatus($event, row.id)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="排序" prop="sort" min-width="100" />
|
||||
<el-table-column label="发布时间" prop="create_time" min-width="120" />
|
||||
<el-table-column label="操作" width="170" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button v-perms="['article.article/edit', 'article.article/add:edit']" type="primary" link>
|
||||
<router-link :to="{
|
||||
path: getRoutePath('article.article/add:edit'),
|
||||
query: {
|
||||
id: row.id
|
||||
}
|
||||
}">
|
||||
编辑
|
||||
</router-link>
|
||||
</el-button>
|
||||
<el-button v-perms="['article.article/delete']" type="danger" link @click="handleDelete(row.id)">
|
||||
删除
|
||||
</el-button>
|
||||
<el-button v-perms="['article.article/detail']" link @click="handleDetail(row.id)">
|
||||
详情
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="flex justify-end mt-4">
|
||||
<pagination v-model="pager" @change="getLists" />
|
||||
</div>
|
||||
</el-card>
|
||||
<detail-popup v-if="showDtail" ref="detailRef" @close="showDtail = false" />
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="articleLists">
|
||||
import { articleLists, articleDelete, articleStatus, articleCateAll, articleDetail } from '@/api/article'
|
||||
import { useDictOptions } from '@/hooks/useDictOptions'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import { getRoutePath } from '@/router'
|
||||
import feedback from '@/utils/feedback'
|
||||
import DetailPopup from './detail.vue'
|
||||
|
||||
|
||||
const queryParams = reactive({
|
||||
title: '',
|
||||
cid: '',
|
||||
is_show: ''
|
||||
})
|
||||
|
||||
const { pager, getLists, resetPage, resetParams } = usePaging({
|
||||
fetchFun: articleLists,
|
||||
params: queryParams
|
||||
})
|
||||
|
||||
const { optionsData } = useDictOptions<{
|
||||
article_cate: any[]
|
||||
}>({
|
||||
article_cate: {
|
||||
api: articleCateAll
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
const changeStatus = async (is_show: any, id: number) => {
|
||||
try {
|
||||
await articleStatus({ id, is_show })
|
||||
getLists()
|
||||
} catch (error) {
|
||||
getLists()
|
||||
}
|
||||
}
|
||||
|
||||
const handleDelete = async (id: number) => {
|
||||
await feedback.confirm('确定要删除?')
|
||||
await articleDelete({ id })
|
||||
getLists()
|
||||
}
|
||||
|
||||
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
|
||||
const showDtail = ref(false)
|
||||
|
||||
|
||||
const handleDetail = async (id: number) => {
|
||||
let res = await articleDetail({ id })
|
||||
showDtail.value = true
|
||||
await nextTick()
|
||||
detailRef.value?.open(res)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
onActivated(() => {
|
||||
getLists()
|
||||
})
|
||||
|
||||
getLists()
|
||||
</script>
|
88
src/views/decoration/component/add-nav.vue
Normal file
88
src/views/decoration/component/add-nav.vue
Normal file
@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<draggable class="draggable" v-model="navLists" animation="300">
|
||||
<template v-slot:item="{ element: item, index }">
|
||||
<del-wrap class="max-w-[400px]" :key="index" @close="handleDelete(index)">
|
||||
<div class="bg-fill-light flex items-center w-full p-4 mb-4 cursor-move">
|
||||
<material-picker
|
||||
v-model="item.image"
|
||||
upload-class="bg-body"
|
||||
size="60px"
|
||||
exclude-domain
|
||||
>
|
||||
<template #upload>
|
||||
<div class="upload-btn w-[60px] h-[60px]">
|
||||
<icon name="el-icon-Plus" :size="20" />
|
||||
</div>
|
||||
</template>
|
||||
</material-picker>
|
||||
<div class="ml-3 flex-1">
|
||||
<div class="flex">
|
||||
<span class="text-tx-regular flex-none mr-3">名称</span>
|
||||
<el-input v-model="item.name" placeholder="请输入名称" />
|
||||
</div>
|
||||
<div class="flex mt-[18px]">
|
||||
<span class="text-tx-regular flex-none mr-3">链接</span>
|
||||
<link-picker v-model="item.link" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</del-wrap>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
<div>
|
||||
<el-button type="primary" @click="handleAdd">添加</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import feedback from '@/utils/feedback'
|
||||
import type { PropType } from 'vue'
|
||||
import Draggable from 'vuedraggable'
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Array as PropType<any[]>,
|
||||
default: () => []
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
min: {
|
||||
type: Number,
|
||||
default: 1
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const navLists = computed({
|
||||
get() {
|
||||
return props.modelValue
|
||||
},
|
||||
set(value) {
|
||||
emit('update:modelValue', value)
|
||||
}
|
||||
})
|
||||
|
||||
const handleAdd = () => {
|
||||
if (props.modelValue?.length < props.max) {
|
||||
navLists.value.push({
|
||||
image: '',
|
||||
name: '导航名称',
|
||||
link: {}
|
||||
})
|
||||
} else {
|
||||
feedback.msgError(`最多添加${props.max}个`)
|
||||
}
|
||||
}
|
||||
const handleDelete = (index: number) => {
|
||||
if (props.modelValue?.length <= props.min) {
|
||||
return feedback.msgError(`最少保留${props.min}个`)
|
||||
}
|
||||
navLists.value.splice(index, 1)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
59
src/views/decoration/component/decoration-img.vue
Normal file
59
src/views/decoration/component/decoration-img.vue
Normal file
@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<el-image :style="styles" v-bind="props" :src="getImageUrl(src)">
|
||||
<template #placeholder>
|
||||
<div class="image-slot"></div>
|
||||
</template>
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<icon name="el-icon-Picture" :size="30" />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import type { CSSProperties } from 'vue'
|
||||
import { addUnit } from '@/utils/util'
|
||||
import { imageProps } from 'element-plus'
|
||||
import useAppStore from '@/stores/modules/app'
|
||||
const props = defineProps({
|
||||
width: {
|
||||
type: [String, Number],
|
||||
default: 'auto'
|
||||
},
|
||||
height: {
|
||||
type: [String, Number],
|
||||
default: 'auto'
|
||||
},
|
||||
radius: {
|
||||
type: [String, Number],
|
||||
default: 0
|
||||
},
|
||||
...imageProps
|
||||
})
|
||||
|
||||
const { getImageUrl } = useAppStore()
|
||||
const styles = computed<CSSProperties>(() => {
|
||||
return {
|
||||
width: addUnit(props.width),
|
||||
height: addUnit(props.height),
|
||||
borderRadius: addUnit(props.radius)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.el-image {
|
||||
display: block;
|
||||
.image-slot {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #fafafa;
|
||||
color: #909399;
|
||||
}
|
||||
}
|
||||
</style>
|
33
src/views/decoration/component/pages/attr-setting.vue
Normal file
33
src/views/decoration/component/pages/attr-setting.vue
Normal file
@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div class="pages-setting">
|
||||
<div
|
||||
class="title flex items-center before:w-[3px] before:h-[14px] before:block before:bg-primary before:mr-2"
|
||||
>
|
||||
{{ widget?.title }}
|
||||
</div>
|
||||
<keep-alive>
|
||||
<component
|
||||
class="pt-5 pr-4"
|
||||
:is="widgets[widget?.name]?.attr"
|
||||
:content="widget?.content"
|
||||
:styles="widget?.styles"
|
||||
:type="type"
|
||||
/>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue'
|
||||
import widgets from '../widgets'
|
||||
|
||||
const props = defineProps({
|
||||
widget: {
|
||||
type: Object as PropType<Record<string, any>>,
|
||||
default: () => ({})
|
||||
},
|
||||
type: {
|
||||
type: String as PropType<'mobile' | 'pc'>,
|
||||
default: 'mobile'
|
||||
}
|
||||
})
|
||||
</script>
|
44
src/views/decoration/component/pages/menu.vue
Normal file
44
src/views/decoration/component/pages/menu.vue
Normal file
@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<el-menu
|
||||
:default-active="modelValue"
|
||||
class="w-[160px] min-h-[668px] pages-menu"
|
||||
@select="handleSelect"
|
||||
>
|
||||
<el-menu-item v-for="(item, key) in menus" :index="key" :key="item.id">
|
||||
<span>{{ item.name }}</span>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue'
|
||||
|
||||
defineProps({
|
||||
menus: {
|
||||
type: Object as PropType<Record<string, any>>,
|
||||
default: () => ({})
|
||||
},
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: '1'
|
||||
}
|
||||
})
|
||||
const emit = defineEmits<{
|
||||
(event: 'update:modelValue', value: string): void
|
||||
}>()
|
||||
const handleSelect = (index: string) => {
|
||||
emit('update:modelValue', index)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pages-menu {
|
||||
:deep(.el-menu-item) {
|
||||
border-color: transparent;
|
||||
&.is-active {
|
||||
border-right-width: 2px;
|
||||
border-color: var(--el-color-primary);
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
67
src/views/decoration/component/pages/preview-pc.vue
Normal file
67
src/views/decoration/component/pages/preview-pc.vue
Normal file
@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div class="pages-preview">
|
||||
<div
|
||||
v-for="(widget, index) in pageData"
|
||||
:key="widget.id"
|
||||
class="relative"
|
||||
:class="{
|
||||
'cursor-pointer': !widget?.disabled
|
||||
}"
|
||||
@click="handleClick(widget, index)"
|
||||
>
|
||||
<div
|
||||
class="absolute w-full h-full z-[100] border-dashed"
|
||||
:class="{
|
||||
select: index == modelValue,
|
||||
'border-[#dcdfe6] border-2': !widget?.disabled
|
||||
}"
|
||||
:style="widget.styles"
|
||||
></div>
|
||||
<slot>
|
||||
<component
|
||||
:is="widgets[widget?.name]?.content"
|
||||
:content="widget.content"
|
||||
:styles="widget.styles"
|
||||
:key="widget.id"
|
||||
/>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import widgets from '../widgets'
|
||||
import type { PropType } from 'vue'
|
||||
|
||||
defineProps({
|
||||
pageData: {
|
||||
type: Array as PropType<any[]>,
|
||||
default: () => []
|
||||
},
|
||||
modelValue: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: 'update:modelValue', value: number): void
|
||||
}>()
|
||||
|
||||
const handleClick = (widget: any, index: number) => {
|
||||
if (widget.disabled) return
|
||||
emit('update:modelValue', index)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pages-preview {
|
||||
width: 460px;
|
||||
height: 360px;
|
||||
background: url(../../image/pc_index.png);
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
.select {
|
||||
@apply border-primary border-solid;
|
||||
}
|
||||
}
|
||||
</style>
|
67
src/views/decoration/component/pages/preview.vue
Normal file
67
src/views/decoration/component/pages/preview.vue
Normal file
@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div class="shadow mx-[30px] pages-preview">
|
||||
<el-scrollbar>
|
||||
<div
|
||||
v-for="(widget, index) in pageData"
|
||||
:key="widget.id"
|
||||
class="relative"
|
||||
:class="{
|
||||
'cursor-pointer': !widget?.disabled
|
||||
}"
|
||||
@click="handleClick(widget, index)"
|
||||
>
|
||||
<div
|
||||
class="absolute w-full h-full z-[100] border-dashed"
|
||||
:class="{
|
||||
select: index == modelValue,
|
||||
'border-[#dcdfe6] border-2': !widget?.disabled
|
||||
}"
|
||||
></div>
|
||||
<slot>
|
||||
<component
|
||||
:is="widgets[widget?.name]?.content"
|
||||
:content="widget.content"
|
||||
:styles="widget.styles"
|
||||
:key="widget.id"
|
||||
/>
|
||||
</slot>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import widgets from '../widgets'
|
||||
import type { PropType } from 'vue'
|
||||
|
||||
defineProps({
|
||||
pageData: {
|
||||
type: Array as PropType<any[]>,
|
||||
default: () => []
|
||||
},
|
||||
modelValue: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: 'update:modelValue', value: number): void
|
||||
}>()
|
||||
|
||||
const handleClick = (widget: any, index: number) => {
|
||||
if (widget.disabled) return
|
||||
emit('update:modelValue', index)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pages-preview {
|
||||
background-color: #f8f8f8;
|
||||
width: 360px;
|
||||
height: 615px;
|
||||
color: #333;
|
||||
.select {
|
||||
@apply border-primary border-solid;
|
||||
}
|
||||
}
|
||||
</style>
|
100
src/views/decoration/component/widgets/banner/attr.vue
Normal file
100
src/views/decoration/component/widgets/banner/attr.vue
Normal file
@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form label-width="70px">
|
||||
<el-form-item label="是否启用" v-if="type == 'mobile'">
|
||||
<el-radio-group v-model="content.enabled">
|
||||
<el-radio :label="1">开启</el-radio>
|
||||
<el-radio :label="0">停用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="图片设置">
|
||||
<div class="flex-1">
|
||||
<div class="form-tips">最多添加5张,建议图片尺寸:750px*340px</div>
|
||||
<draggable class="draggable" v-model="content.data" animation="300">
|
||||
<template v-slot:item="{ element: item, index }">
|
||||
<del-wrap
|
||||
:key="index"
|
||||
@close="handleDelete(index)"
|
||||
class="max-w-[400px]"
|
||||
>
|
||||
<div
|
||||
class="bg-fill-light flex items-center w-full p-4 mt-4 cursor-move"
|
||||
>
|
||||
<material-picker
|
||||
v-model="item.image"
|
||||
upload-class="bg-body"
|
||||
exclude-domain
|
||||
/>
|
||||
<div class="ml-3 flex-1">
|
||||
<el-form-item label="图片名称">
|
||||
<el-input
|
||||
v-model="item.name"
|
||||
placeholder="请输入名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mt-[18px]" label="图片链接">
|
||||
<link-picker
|
||||
v-if="type == 'mobile'"
|
||||
v-model="item.link"
|
||||
/>
|
||||
<el-input
|
||||
v-if="type == 'pc'"
|
||||
placeholder="请输入链接"
|
||||
v-model="item.link.path"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
</del-wrap>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="content.data?.length < limit">
|
||||
<el-button type="primary" @click="handleAdd">添加图片</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import feedback from '@/utils/feedback'
|
||||
import type { PropType } from 'vue'
|
||||
import type options from './options'
|
||||
import Draggable from 'vuedraggable'
|
||||
const limit = 5
|
||||
type OptionsType = ReturnType<typeof options>
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: Object as PropType<OptionsType['content']>,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object as PropType<OptionsType['styles']>,
|
||||
default: () => ({})
|
||||
},
|
||||
type: {
|
||||
type: String as PropType<'mobile' | 'pc'>,
|
||||
default: 'mobile'
|
||||
}
|
||||
})
|
||||
|
||||
const handleAdd = () => {
|
||||
if (props.content.data?.length < limit) {
|
||||
props.content.data.push({
|
||||
image: '',
|
||||
name: '',
|
||||
link: {}
|
||||
})
|
||||
} else {
|
||||
feedback.msgError(`最多添加${limit}张图片`)
|
||||
}
|
||||
}
|
||||
const handleDelete = (index: number) => {
|
||||
if (props.content.data?.length <= 1) {
|
||||
return feedback.msgError('最少保留一张图片')
|
||||
}
|
||||
props.content.data.splice(index, 1)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
42
src/views/decoration/component/widgets/banner/content.vue
Normal file
42
src/views/decoration/component/widgets/banner/content.vue
Normal file
@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div class="banner" :style="styles">
|
||||
<div class="banner-image w-full h-full">
|
||||
<decoration-img
|
||||
width="100%"
|
||||
:height="styles.height || height"
|
||||
:src="getImage"
|
||||
fit="contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue'
|
||||
import type options from './options'
|
||||
import DecorationImg from '../../decoration-img.vue'
|
||||
type OptionsType = ReturnType<typeof options>
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: Object as PropType<OptionsType['content']>,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object as PropType<OptionsType['styles']>,
|
||||
default: () => ({})
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '170px'
|
||||
}
|
||||
})
|
||||
|
||||
const getImage = computed(() => {
|
||||
const { data } = props.content
|
||||
if (Array.isArray(data)) {
|
||||
return data[0] ? data[0].image : ''
|
||||
}
|
||||
return ''
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
8
src/views/decoration/component/widgets/banner/index.ts
Normal file
8
src/views/decoration/component/widgets/banner/index.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import attr from './attr.vue'
|
||||
import content from './content.vue'
|
||||
import options from './options'
|
||||
export default {
|
||||
attr,
|
||||
content,
|
||||
options
|
||||
}
|
15
src/views/decoration/component/widgets/banner/options.ts
Normal file
15
src/views/decoration/component/widgets/banner/options.ts
Normal file
@ -0,0 +1,15 @@
|
||||
export default () => ({
|
||||
title: '首页轮播图',
|
||||
name: 'banner',
|
||||
content: {
|
||||
enabled: 1,
|
||||
data: [
|
||||
{
|
||||
image: '',
|
||||
name: '',
|
||||
link: {}
|
||||
}
|
||||
]
|
||||
},
|
||||
styles: {}
|
||||
})
|
@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form label-width="90px">
|
||||
<el-form-item label="客服标题">
|
||||
<el-input class="w-[400px]" v-model="content.title" />
|
||||
</el-form-item>
|
||||
<el-form-item label="服务时间">
|
||||
<el-input class="w-[400px]" v-model="content.time" />
|
||||
</el-form-item>
|
||||
<el-form-item label="联系电话">
|
||||
<el-input class="w-[400px]" v-model="content.mobile" />
|
||||
</el-form-item>
|
||||
<el-form-item label="客服二维码">
|
||||
<div>
|
||||
<material-picker v-model="content.qrcode" exclude-domain />
|
||||
<div class="form-tips">建议图片尺寸:200*200像素;图片格式:jpg、png、jpeg</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue'
|
||||
import type options from './options'
|
||||
type OptionsType = ReturnType<typeof options>
|
||||
defineProps({
|
||||
content: {
|
||||
type: Object as PropType<OptionsType['content']>,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object as PropType<OptionsType['styles']>,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div class="customer-service">
|
||||
<decoration-img width="140px" height="140px" :src="content.qrcode" alt="" />
|
||||
<div class="text-[15px] mt-[7px] font-medium">{{ content.title }}</div>
|
||||
<div class="text-[#666] mt-[20px]">服务时间:{{ content.time }}</div>
|
||||
<div class="text-[#666] mt-[7px]">客服电话:{{ content.mobile }}</div>
|
||||
<div
|
||||
class="text-white text-[16px] rounded-[42px] bg-[#4173FF] w-full h-[42px] flex justify-center items-center mt-[50px]"
|
||||
>
|
||||
保存二维码图片
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue'
|
||||
import type options from './options'
|
||||
import DecorationImg from '../../decoration-img.vue'
|
||||
type OptionsType = ReturnType<typeof options>
|
||||
defineProps({
|
||||
content: {
|
||||
type: Object as PropType<OptionsType['content']>,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object as PropType<OptionsType['styles']>,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.customer-service {
|
||||
margin: 10px 18px;
|
||||
border-radius: 10px;
|
||||
padding: 50px 55px 80px;
|
||||
background: #fff;
|
||||
@apply flex flex-col justify-center items-center;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,8 @@
|
||||
import attr from './attr.vue'
|
||||
import content from './content.vue'
|
||||
import options from './options'
|
||||
export default {
|
||||
attr,
|
||||
content,
|
||||
options
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
export default () => ({
|
||||
title: '客服设置',
|
||||
name: 'customer-service',
|
||||
content: {
|
||||
title: '添加客服二维码',
|
||||
time: '',
|
||||
mobile: '',
|
||||
qrcode: ''
|
||||
},
|
||||
styles: {}
|
||||
})
|
13
src/views/decoration/component/widgets/index.ts
Normal file
13
src/views/decoration/component/widgets/index.ts
Normal file
@ -0,0 +1,13 @@
|
||||
const widgets: Record<string, any> = import.meta.glob('./**/index.ts', { eager: true })
|
||||
interface Widget {
|
||||
attr: any
|
||||
content: any
|
||||
options: any
|
||||
}
|
||||
const exportWidgets: Record<string, Widget> = {}
|
||||
Object.keys(widgets).forEach((key) => {
|
||||
const widgetName = key.replace(/^\.\/([\w-]+).*/gi, '$1')
|
||||
exportWidgets[widgetName] = widgets[key]?.default
|
||||
})
|
||||
|
||||
export default exportWidgets
|
38
src/views/decoration/component/widgets/my-service/attr.vue
Normal file
38
src/views/decoration/component/widgets/my-service/attr.vue
Normal file
@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form label-width="70px">
|
||||
<el-form-item label="排版样式">
|
||||
<el-radio-group v-model="content.style">
|
||||
<el-radio :label="1">横排</el-radio>
|
||||
<el-radio :label="2">竖排</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="标题名称">
|
||||
<el-input class="w-[400px]" v-model="content.title" />
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单设置">
|
||||
<div class="flex-1">
|
||||
<AddNav v-model="content.data" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue'
|
||||
import type options from './options'
|
||||
import AddNav from '../../add-nav.vue'
|
||||
type OptionsType = ReturnType<typeof options>
|
||||
defineProps({
|
||||
content: {
|
||||
type: Object as PropType<OptionsType['content']>,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object as PropType<OptionsType['styles']>,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<div class="my-service">
|
||||
<div v-if="content.title" class="title px-[15px] py-[10px]">
|
||||
<div>{{ content.title }}</div>
|
||||
</div>
|
||||
<div v-if="content.style == 1" class="flex flex-wrap pt-[20px] pb-[10px]">
|
||||
<div
|
||||
v-for="(item, index) in content.data"
|
||||
:key="index"
|
||||
class="flex flex-col items-center w-1/4 mb-[15px]"
|
||||
>
|
||||
<decoration-img width="26px" height="26px" :src="item.image" alt="" />
|
||||
<div class="mt-[7px]">{{ item.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="content.style == 2">
|
||||
<div
|
||||
v-for="(item, index) in content.data"
|
||||
:key="index"
|
||||
class="flex items-center border-b border-[#e5e5e5] h-[50px] px-[12px]"
|
||||
>
|
||||
<decoration-img width="24px" height="24px" :src="item.image" alt="" />
|
||||
<div class="ml-[10px] flex-1">{{ item.name }}</div>
|
||||
<div>
|
||||
<icon name="el-icon-ArrowRight" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue'
|
||||
import type options from './options'
|
||||
import DecorationImg from '../../decoration-img.vue'
|
||||
type OptionsType = ReturnType<typeof options>
|
||||
defineProps({
|
||||
content: {
|
||||
type: Object as PropType<OptionsType['content']>,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object as PropType<OptionsType['styles']>,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.my-service {
|
||||
margin: 10px 10px 0;
|
||||
background-color: #fff;
|
||||
border-radius: 7px;
|
||||
.title {
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,8 @@
|
||||
import attr from './attr.vue'
|
||||
import content from './content.vue'
|
||||
import options from './options'
|
||||
export default {
|
||||
attr,
|
||||
content,
|
||||
options
|
||||
}
|
16
src/views/decoration/component/widgets/my-service/options.ts
Normal file
16
src/views/decoration/component/widgets/my-service/options.ts
Normal file
@ -0,0 +1,16 @@
|
||||
export default () => ({
|
||||
title: '我的服务',
|
||||
name: 'my-service',
|
||||
content: {
|
||||
style: 1,
|
||||
title: '我的服务',
|
||||
data: [
|
||||
{
|
||||
image: '',
|
||||
name: '导航名称',
|
||||
link: {}
|
||||
}
|
||||
]
|
||||
},
|
||||
styles: {}
|
||||
})
|
36
src/views/decoration/component/widgets/nav/attr.vue
Normal file
36
src/views/decoration/component/widgets/nav/attr.vue
Normal file
@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form label-width="70px">
|
||||
<el-form-item label="是否启用">
|
||||
<el-radio-group v-model="content.enabled">
|
||||
<el-radio :label="1">开启</el-radio>
|
||||
<el-radio :label="0">停用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单设置">
|
||||
<div class="flex-1">
|
||||
<div class="form-tips mb-4">最多可添加10个,建议图片尺寸:100px*100px</div>
|
||||
<AddNav v-model="content.data" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue'
|
||||
import type options from './options'
|
||||
import AddNav from '../../add-nav.vue'
|
||||
type OptionsType = ReturnType<typeof options>
|
||||
defineProps({
|
||||
content: {
|
||||
type: Object as PropType<OptionsType['content']>,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object as PropType<OptionsType['styles']>,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
32
src/views/decoration/component/widgets/nav/content.vue
Normal file
32
src/views/decoration/component/widgets/nav/content.vue
Normal file
@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<div class="nav bg-white pt-[15px] pb-[8px]">
|
||||
<div class="flex flex-wrap">
|
||||
<div
|
||||
v-for="(item, index) in content.data"
|
||||
:key="index"
|
||||
class="flex flex-col items-center w-1/5 mb-[15px]"
|
||||
>
|
||||
<decoration-img width="41px" height="41px" :src="item.image" alt="" />
|
||||
<div class="mt-[7px]">{{ item.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue'
|
||||
import type options from './options'
|
||||
import DecorationImg from '../../decoration-img.vue'
|
||||
type OptionsType = ReturnType<typeof options>
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: Object as PropType<OptionsType['content']>,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object as PropType<OptionsType['styles']>,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
8
src/views/decoration/component/widgets/nav/index.ts
Normal file
8
src/views/decoration/component/widgets/nav/index.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import attr from './attr.vue'
|
||||
import content from './content.vue'
|
||||
import options from './options'
|
||||
export default {
|
||||
attr,
|
||||
content,
|
||||
options
|
||||
}
|
15
src/views/decoration/component/widgets/nav/options.ts
Normal file
15
src/views/decoration/component/widgets/nav/options.ts
Normal file
@ -0,0 +1,15 @@
|
||||
export default () => ({
|
||||
title: '导航菜单',
|
||||
name: 'nav',
|
||||
content: {
|
||||
enabled: 1,
|
||||
data: [
|
||||
{
|
||||
image: '',
|
||||
name: '导航名称',
|
||||
link: {}
|
||||
}
|
||||
]
|
||||
},
|
||||
styles: {}
|
||||
})
|
20
src/views/decoration/component/widgets/news/attr.vue
Normal file
20
src/views/decoration/component/widgets/news/attr.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue'
|
||||
import type options from './options'
|
||||
type OptionsType = ReturnType<typeof options>
|
||||
defineProps({
|
||||
content: {
|
||||
type: Object as PropType<OptionsType['content']>,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object as PropType<OptionsType['styles']>,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
70
src/views/decoration/component/widgets/news/content.vue
Normal file
70
src/views/decoration/component/widgets/news/content.vue
Normal file
@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<div class="news">
|
||||
<div class="flex items-center news-title mx-[10px] my-[15px] text-[17px] font-medium">
|
||||
最新资讯
|
||||
</div>
|
||||
<div
|
||||
v-for="item in newsList"
|
||||
:key="item.id"
|
||||
class="news-card flex bg-white px-[10px] py-[16px] text-[#333] border-[#f2f2f2] border-b"
|
||||
>
|
||||
<div class="mr-[10px]" v-if="item.image">
|
||||
<img :src="item.image" class="w-[120px] h-[90px] object-contain" />
|
||||
</div>
|
||||
<div class="flex flex-col justify-between flex-1">
|
||||
<div class="text-[15px] font-medium line-clamp-2">{{ item.title }}</div>
|
||||
<div class="line-clamp-1 text-sm mt-[8px]">
|
||||
{{ item.desc }}
|
||||
</div>
|
||||
|
||||
<div class="text-[#999] text-xs w-full flex justify-between mt-[8px]">
|
||||
<div>{{ item.create_time }}</div>
|
||||
<div class="flex items-center">
|
||||
<icon name="el-icon-View" />
|
||||
<div class="ml-[5px]">{{ item.click }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue'
|
||||
import { getDecorateArticle } from '@/api/decoration'
|
||||
import type options from './options'
|
||||
type OptionsType = ReturnType<typeof options>
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: Object as PropType<OptionsType['content']>,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object as PropType<OptionsType['styles']>,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
const newsList = ref<any[]>([])
|
||||
const getData = async () => {
|
||||
const data = await getDecorateArticle({
|
||||
limit: 10
|
||||
})
|
||||
newsList.value = data
|
||||
}
|
||||
getData()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.news {
|
||||
.news-title {
|
||||
&::before {
|
||||
content: '';
|
||||
width: 4px;
|
||||
height: 17px;
|
||||
display: block;
|
||||
margin-right: 5px;
|
||||
background: #4173ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
8
src/views/decoration/component/widgets/news/index.ts
Normal file
8
src/views/decoration/component/widgets/news/index.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import attr from './attr.vue'
|
||||
import content from './content.vue'
|
||||
import options from './options'
|
||||
export default {
|
||||
attr,
|
||||
content,
|
||||
options
|
||||
}
|
7
src/views/decoration/component/widgets/news/options.ts
Normal file
7
src/views/decoration/component/widgets/news/options.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export default () => ({
|
||||
title: '资讯',
|
||||
name: 'news',
|
||||
disabled: 1,
|
||||
content: {},
|
||||
styles: {}
|
||||
})
|
20
src/views/decoration/component/widgets/search/attr.vue
Normal file
20
src/views/decoration/component/widgets/search/attr.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue'
|
||||
import type options from './options'
|
||||
type OptionsType = ReturnType<typeof options>
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: Object as PropType<OptionsType['content']>,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object as PropType<OptionsType['styles']>,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
23
src/views/decoration/component/widgets/search/content.vue
Normal file
23
src/views/decoration/component/widgets/search/content.vue
Normal file
@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<div class="search-con flex items-center px-[15px]">
|
||||
<icon name="el-icon-Search" :size="17" />
|
||||
<span class="ml-[5px]">请输入关键词搜索</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search {
|
||||
background-color: #fff;
|
||||
padding: 7px 12px;
|
||||
.search-con {
|
||||
height: 100%;
|
||||
height: 36px;
|
||||
border-radius: 36px;
|
||||
background: #f4f4f4;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
</style>
|
8
src/views/decoration/component/widgets/search/index.ts
Normal file
8
src/views/decoration/component/widgets/search/index.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import attr from './attr.vue'
|
||||
import content from './content.vue'
|
||||
import options from './options'
|
||||
export default {
|
||||
attr,
|
||||
content,
|
||||
options
|
||||
}
|
7
src/views/decoration/component/widgets/search/options.ts
Normal file
7
src/views/decoration/component/widgets/search/options.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export default () => ({
|
||||
title: '搜索',
|
||||
name: 'search',
|
||||
disabled: 1,
|
||||
content: {},
|
||||
styles: {}
|
||||
})
|
88
src/views/decoration/component/widgets/user-banner/attr.vue
Normal file
88
src/views/decoration/component/widgets/user-banner/attr.vue
Normal file
@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form label-width="70px">
|
||||
<el-form-item label="是否启用">
|
||||
<el-radio-group v-model="content.enabled">
|
||||
<el-radio :label="1">开启</el-radio>
|
||||
<el-radio :label="0">停用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="图片设置">
|
||||
<div class="flex-1">
|
||||
<div class="form-tips">最多添加5张,建议图片尺寸:750px*200px</div>
|
||||
<draggable class="draggable" v-model="content.data" animation="300">
|
||||
<template v-slot:item="{ element: item, index }">
|
||||
<del-wrap
|
||||
:key="index"
|
||||
@close="handleDelete(index)"
|
||||
class="max-w-[400px]"
|
||||
>
|
||||
<div
|
||||
class="bg-fill-light flex items-center w-full p-4 mt-4 cursor-move"
|
||||
>
|
||||
<material-picker
|
||||
v-model="item.image"
|
||||
upload-class="bg-body"
|
||||
exclude-domain
|
||||
/>
|
||||
<div class="ml-3 flex-1">
|
||||
<el-form-item label="图片名称">
|
||||
<el-input
|
||||
v-model="item.name"
|
||||
placeholder="请输入名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mt-[18px]" label="图片链接">
|
||||
<link-picker v-model="item.link" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
</del-wrap>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="content.data?.length < limit">
|
||||
<el-button type="primary" @click="handleAdd">添加图片</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import feedback from '@/utils/feedback'
|
||||
import type { PropType } from 'vue'
|
||||
import type options from './options'
|
||||
import Draggable from 'vuedraggable'
|
||||
const limit = 5
|
||||
type OptionsType = ReturnType<typeof options>
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: Object as PropType<OptionsType['content']>,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object as PropType<OptionsType['styles']>,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
|
||||
const handleAdd = () => {
|
||||
if (props.content.data?.length < limit) {
|
||||
props.content.data.push({
|
||||
image: '',
|
||||
name: '',
|
||||
link: {}
|
||||
})
|
||||
} else {
|
||||
feedback.msgError(`最多添加${limit}张图片`)
|
||||
}
|
||||
}
|
||||
const handleDelete = (index: number) => {
|
||||
if (props.content.data?.length <= 1) {
|
||||
return feedback.msgError('最少保留一张图片')
|
||||
}
|
||||
props.content.data.splice(index, 1)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<div class="banner mx-[10px] mt-[10px]">
|
||||
<div class="banner-image">
|
||||
<decoration-img width="100%" height="100px" :src="getImage" fit="contain" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue'
|
||||
import type options from './options'
|
||||
import DecorationImg from '../../decoration-img.vue'
|
||||
type OptionsType = ReturnType<typeof options>
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: Object as PropType<OptionsType['content']>,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object as PropType<OptionsType['styles']>,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
const getImage = computed(() => {
|
||||
const { data } = props.content
|
||||
if (Array.isArray(data)) {
|
||||
return data[0] ? data[0].image : ''
|
||||
}
|
||||
return ''
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,8 @@
|
||||
import attr from './attr.vue'
|
||||
import content from './content.vue'
|
||||
import options from './options'
|
||||
export default {
|
||||
attr,
|
||||
content,
|
||||
options
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
export default () => ({
|
||||
title: '个人中心广告图',
|
||||
name: 'user-banner',
|
||||
content: {
|
||||
enabled: 1,
|
||||
data: [
|
||||
{
|
||||
image: '',
|
||||
name: '',
|
||||
link: {}
|
||||
}
|
||||
]
|
||||
},
|
||||
styles: {}
|
||||
})
|
20
src/views/decoration/component/widgets/user-info/attr.vue
Normal file
20
src/views/decoration/component/widgets/user-info/attr.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue'
|
||||
import type options from './options'
|
||||
type OptionsType = ReturnType<typeof options>
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: Object as PropType<OptionsType['content']>,
|
||||
default: () => ({})
|
||||
},
|
||||
styles: {
|
||||
type: Object as PropType<OptionsType['styles']>,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
16
src/views/decoration/component/widgets/user-info/content.vue
Normal file
16
src/views/decoration/component/widgets/user-info/content.vue
Normal file
@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<div class="user-info flex items-center px-[25px]">
|
||||
<img src="./images/default_avatar.png" class="w-[60px] h-[60px]" alt="" />
|
||||
<div class="text-white text-[18px] ml-[10px]">未登录</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.user-info {
|
||||
background: url(./images/my_topbg.png);
|
||||
height: 115px;
|
||||
background-position: bottom;
|
||||
background-size: 100% auto;
|
||||
}
|
||||
</style>
|
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 139 KiB |
@ -0,0 +1,8 @@
|
||||
import attr from './attr.vue'
|
||||
import content from './content.vue'
|
||||
import options from './options'
|
||||
export default {
|
||||
attr,
|
||||
content,
|
||||
options
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
export default () => ({
|
||||
title: '用户信息',
|
||||
name: 'user-info',
|
||||
disabled: 1,
|
||||
content: {},
|
||||
styles: {}
|
||||
})
|
BIN
src/views/decoration/image/pc_index.png
Normal file
BIN
src/views/decoration/image/pc_index.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 516 KiB |
103
src/views/decoration/pages/index.vue
Normal file
103
src/views/decoration/pages/index.vue
Normal file
@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<div class="decoration-pages min-w-[1100px]">
|
||||
<el-card shadow="never" class="!border-none flex-1 flex" :body-style="{ flex: 1 }">
|
||||
<div class="flex h-full items-start">
|
||||
<Menu v-model="activeMenu" :menus="menus" />
|
||||
<preview v-model="selectWidgetIndex" :pageData="getPageData" />
|
||||
<attr-setting class="flex-1" :widget="getSelectWidget" />
|
||||
</div>
|
||||
</el-card>
|
||||
<footer-btns class="mt-4" :fixed="false" v-perms="['decorate:pages:save']">
|
||||
<el-button type="primary" @click="setData">保存</el-button>
|
||||
</footer-btns>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="decorationPages">
|
||||
import Menu from '../component/pages/menu.vue'
|
||||
import Preview from '../component/pages/preview.vue'
|
||||
import AttrSetting from '../component/pages/attr-setting.vue'
|
||||
import widgets from '../component/widgets'
|
||||
import { getDecoratePages, setDecoratePages } from '@/api/decoration'
|
||||
import { getNonDuplicateID } from '@/utils/util'
|
||||
enum pagesTypeEnum {
|
||||
HOME = '1',
|
||||
USER = '2',
|
||||
SERVICE = '3'
|
||||
}
|
||||
|
||||
const generatePageData = (widgetNames: string[]) => {
|
||||
return widgetNames.map((widgetName) => {
|
||||
const options = {
|
||||
id: getNonDuplicateID(),
|
||||
...(widgets[widgetName]?.options() || {})
|
||||
}
|
||||
return options
|
||||
})
|
||||
}
|
||||
|
||||
const menus: Record<
|
||||
string,
|
||||
{
|
||||
id: number
|
||||
name: string
|
||||
pageData: any[]
|
||||
}
|
||||
> = reactive({
|
||||
[pagesTypeEnum.HOME]: {
|
||||
id: 1,
|
||||
type: 1,
|
||||
name: '首页装修',
|
||||
pageData: generatePageData(['search', 'banner', 'nav', 'news'])
|
||||
},
|
||||
[pagesTypeEnum.USER]: {
|
||||
id: 2,
|
||||
type: 2,
|
||||
name: '个人中心',
|
||||
pageData: generatePageData(['user-info', 'my-service', 'user-banner'])
|
||||
},
|
||||
[pagesTypeEnum.SERVICE]: {
|
||||
id: 3,
|
||||
type: 3,
|
||||
name: '客服设置',
|
||||
pageData: generatePageData(['customer-service'])
|
||||
}
|
||||
})
|
||||
|
||||
const activeMenu = ref('1')
|
||||
const selectWidgetIndex = ref(-1)
|
||||
const getPageData = computed(() => {
|
||||
return menus[activeMenu.value]?.pageData ?? []
|
||||
})
|
||||
const getSelectWidget = computed(() => {
|
||||
return menus[activeMenu.value]?.pageData[selectWidgetIndex.value] ?? ''
|
||||
})
|
||||
|
||||
const getData = async () => {
|
||||
const data = await getDecoratePages({ id: activeMenu.value })
|
||||
menus[String(data.id)].pageData = JSON.parse(data.data)
|
||||
}
|
||||
|
||||
const setData = async () => {
|
||||
await setDecoratePages({
|
||||
...menus[activeMenu.value],
|
||||
data: JSON.stringify(menus[activeMenu.value].pageData)
|
||||
})
|
||||
getData()
|
||||
}
|
||||
watch(
|
||||
activeMenu,
|
||||
() => {
|
||||
selectWidgetIndex.value = getPageData.value.findIndex((item) => !item.disabled)
|
||||
getData()
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.decoration-pages {
|
||||
min-height: calc(100vh - var(--navbar-height) - 80px);
|
||||
@apply flex flex-col;
|
||||
}
|
||||
</style>
|
90
src/views/decoration/pc.vue
Normal file
90
src/views/decoration/pc.vue
Normal file
@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<div class="decoration-pages min-w-[1100px]">
|
||||
<el-card shadow="never" class="!border-none flex-1 flex" :body-style="{ flex: 1 }">
|
||||
<div class="flex h-full items-start">
|
||||
<Menu v-model="activeMenu" :menus="menus" />
|
||||
<preview-pc class="mx-4" v-model="selectWidgetIndex" :pageData="getPageData" />
|
||||
<attr-setting class="flex-1" :widget="getSelectWidget" type="pc" />
|
||||
</div>
|
||||
</el-card>
|
||||
<footer-btns class="mt-4" :fixed="false" v-perms="['decorate:pages:save']">
|
||||
<el-button type="primary" @click="setData">保存</el-button>
|
||||
</footer-btns>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="decorationPc">
|
||||
import Menu from './component/pages/menu.vue'
|
||||
import PreviewPc from './component/pages/preview-pc.vue'
|
||||
import AttrSetting from './component/pages/attr-setting.vue'
|
||||
import widgets from './component/widgets'
|
||||
import { getDecoratePages, setDecoratePages } from '@/api/decoration'
|
||||
import { getNonDuplicateID } from '@/utils/util'
|
||||
enum pagesTypeEnum {
|
||||
HOME = '4'
|
||||
}
|
||||
|
||||
const generatePageData = (widgetNames: string[]) => {
|
||||
return widgetNames.map((widgetName) => {
|
||||
const options = {
|
||||
id: getNonDuplicateID(),
|
||||
...(widgets[widgetName]?.options() || {})
|
||||
}
|
||||
return options
|
||||
})
|
||||
}
|
||||
|
||||
const menus: Record<
|
||||
string,
|
||||
{
|
||||
id: number
|
||||
name: string
|
||||
pageData: any[]
|
||||
}
|
||||
> = reactive({
|
||||
[pagesTypeEnum.HOME]: {
|
||||
id: 4,
|
||||
type: 4,
|
||||
name: '首页装修',
|
||||
pageData: []
|
||||
}
|
||||
})
|
||||
|
||||
const activeMenu = ref('4')
|
||||
const selectWidgetIndex = ref(0)
|
||||
const getPageData = computed(() => {
|
||||
return menus[activeMenu.value]?.pageData ?? []
|
||||
})
|
||||
const getSelectWidget = computed(() => {
|
||||
return menus[activeMenu.value]?.pageData[selectWidgetIndex.value] ?? ''
|
||||
})
|
||||
|
||||
const getData = async () => {
|
||||
const data = await getDecoratePages({ id: activeMenu.value })
|
||||
menus[String(data.id)].pageData = JSON.parse(data.data)
|
||||
selectWidgetIndex.value = getPageData.value.findIndex((item) => !item.disabled)
|
||||
}
|
||||
|
||||
const setData = async () => {
|
||||
await setDecoratePages({
|
||||
...menus[activeMenu.value],
|
||||
data: JSON.stringify(menus[activeMenu.value].pageData)
|
||||
})
|
||||
getData()
|
||||
}
|
||||
watch(
|
||||
activeMenu,
|
||||
() => {
|
||||
selectWidgetIndex.value = getPageData.value.findIndex((item) => !item.disabled)
|
||||
getData()
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.decoration-pages {
|
||||
min-height: calc(100vh - var(--navbar-height) - 80px);
|
||||
@apply flex flex-col;
|
||||
}
|
||||
</style>
|
217
src/views/decoration/tabbar.vue
Normal file
217
src/views/decoration/tabbar.vue
Normal file
@ -0,0 +1,217 @@
|
||||
<template>
|
||||
<div class="decoration-tabbar min-w-[800px]">
|
||||
<el-card shadow="never" class="!border-none flex-1" :body-style="{ height: '100%' }">
|
||||
<div class="flex h-full items-start">
|
||||
<div class="pages-preview mx-[30px]">
|
||||
<div class="tabbar flex">
|
||||
<div
|
||||
class="tabbar-item flex flex-col justify-center items-center flex-1"
|
||||
v-for="(item, index) in tabbar.list"
|
||||
:key="index"
|
||||
:style="{ color: tabbar.style.default_color }"
|
||||
>
|
||||
<img class="w-[22px] h-[22px]" :src="item.unselected" alt="" />
|
||||
<div class="leading-3 text-[12px] mt-[4px]">{{ item.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div
|
||||
class="title flex items-center before:w-[3px] before:h-[14px] before:block before:bg-primary before:mr-2"
|
||||
>
|
||||
底部导航设置
|
||||
<span class="form-tips ml-[10px] !mt-0">
|
||||
至少添加2个导航,最多添加5个导航
|
||||
</span>
|
||||
</div>
|
||||
<el-form class="mt-4" label-width="70px">
|
||||
<el-tabs model-value="content">
|
||||
<el-tab-pane label="导航图片" name="content">
|
||||
<div class="mb-[18px]">
|
||||
<draggable
|
||||
class="draggable"
|
||||
v-model="tabbar.list"
|
||||
animation="300"
|
||||
draggable=".draggable"
|
||||
:move="onMove"
|
||||
>
|
||||
<template v-slot:item="{ element, index }">
|
||||
<del-wrap
|
||||
@close="handleDelete(index)"
|
||||
class="max-w-[400px]"
|
||||
:class="{ draggable: index != 0 }"
|
||||
>
|
||||
<div class="bg-fill-light w-full p-4 mt-4">
|
||||
<el-form-item label="导航图标">
|
||||
<material-picker
|
||||
v-model="element.unselected"
|
||||
upload-class="bg-body"
|
||||
size="60px"
|
||||
>
|
||||
<template #upload>
|
||||
<div
|
||||
class="upload-btn w-[60px] h-[60px]"
|
||||
>
|
||||
<icon
|
||||
name="el-icon-Plus"
|
||||
:size="16"
|
||||
/>
|
||||
<span class="text-xs leading-5">
|
||||
未选中
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</material-picker>
|
||||
<material-picker
|
||||
v-model="element.selected"
|
||||
upload-class="bg-body"
|
||||
size="60px"
|
||||
>
|
||||
<template #upload>
|
||||
<div
|
||||
class="upload-btn w-[60px] h-[60px]"
|
||||
>
|
||||
<icon
|
||||
name="el-icon-Plus"
|
||||
:size="16"
|
||||
/>
|
||||
<span class="text-xs leading-5">
|
||||
选中
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</material-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="导航名称">
|
||||
<el-input
|
||||
v-model="element.name"
|
||||
placeholder="请输入名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="链接地址">
|
||||
<link-picker v-model="element.link" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</del-wrap>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
|
||||
<el-form-item v-if="tabbar.list?.length < max" label-width="0">
|
||||
<el-button type="primary" @click="handleAdd">
|
||||
添加导航
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="样式设置" name="styles">
|
||||
<el-form-item label="默认颜色">
|
||||
<color-picker
|
||||
class="max-w-[400px]"
|
||||
v-model="tabbar.style.default_color"
|
||||
default-color="#999999"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="选中颜色">
|
||||
<color-picker
|
||||
class="max-w-[400px]"
|
||||
v-model="tabbar.style.selected_color"
|
||||
default-color="#4173ff"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<footer-btns class="mt-4" :fixed="false" v-perms="['decorate:tabbar:save']">
|
||||
<el-button type="primary" @click="setData">保存</el-button>
|
||||
</footer-btns>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="decorationTabbar">
|
||||
import { getDecorateTabbar, setDecorateTabbar } from '@/api/decoration'
|
||||
import feedback from '@/utils/feedback'
|
||||
import Draggable from 'vuedraggable'
|
||||
|
||||
const max = 5
|
||||
const min = 2
|
||||
const tabbar = reactive({
|
||||
style: {
|
||||
default_color: '',
|
||||
selected_color: ''
|
||||
},
|
||||
list: [
|
||||
{
|
||||
name: '',
|
||||
selected: '',
|
||||
unselected: '',
|
||||
link: {}
|
||||
},
|
||||
{
|
||||
name: '',
|
||||
selected: '',
|
||||
unselected: '',
|
||||
link: {}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
const handleAdd = () => {
|
||||
if (tabbar.list?.length < max) {
|
||||
tabbar.list.push({
|
||||
name: '',
|
||||
selected: '',
|
||||
unselected: '',
|
||||
link: {}
|
||||
})
|
||||
} else {
|
||||
feedback.msgError(`最多添加${max}个`)
|
||||
}
|
||||
}
|
||||
const handleDelete = (index: number) => {
|
||||
if (tabbar.list?.length <= min) {
|
||||
return feedback.msgError(`最少保留${min}个`)
|
||||
}
|
||||
tabbar.list.splice(index, 1)
|
||||
}
|
||||
|
||||
const onMove = (e: any) => {
|
||||
if (e.relatedContext.index == 0) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const getData = async () => {
|
||||
const data = await getDecorateTabbar()
|
||||
tabbar.list = data.list
|
||||
tabbar.style = data.style
|
||||
}
|
||||
const setData = async () => {
|
||||
await setDecorateTabbar(toRaw(tabbar))
|
||||
getData()
|
||||
}
|
||||
getData()
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.decoration-tabbar {
|
||||
min-height: calc(100vh - var(--navbar-height) - 80px);
|
||||
@apply flex flex-col;
|
||||
.pages-preview {
|
||||
background-color: #f7f7f7;
|
||||
width: 360px;
|
||||
height: 615px;
|
||||
color: #333;
|
||||
position: relative;
|
||||
.tabbar {
|
||||
position: absolute;
|
||||
height: 50px;
|
||||
background-color: #fff;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
border: 2px solid var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
80
src/views/oa_CopyMe/index.vue
Normal file
80
src/views/oa_CopyMe/index.vue
Normal file
@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
|
||||
<div class="mt-4">
|
||||
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="id" prop="id" show-overflow-tooltip />
|
||||
<el-table-column label="申请人" prop="user_name" show-overflow-tooltip />
|
||||
<el-table-column label="申请时间" prop="create_time" show-overflow-tooltip />
|
||||
<el-table-column label="审批类型" prop="type_name" show-overflow-tooltip />
|
||||
<el-table-column label="所属部门" prop="dept_name" show-overflow-tooltip />
|
||||
<el-table-column label="当前审批人" prop="check_admin_users" show-overflow-tooltip />
|
||||
<el-table-column label="审批状态" prop="check_status_text" show-overflow-tooltip />
|
||||
<el-table-column label="备注" prop="remarks" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="handDetail(row)">
|
||||
详情
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="flex mt-4 justify-end">
|
||||
<pagination v-model="pager" @change="getLists" />
|
||||
</div>
|
||||
</el-card>
|
||||
<detailPopup v-if="showDetail" ref="detailRef" @success="showDetail = false, getLists()"
|
||||
@close="showDetail = false, getLists()" :typeName="typeName" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="oaSealCateLists">
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import { useDictData } from '@/hooks/useDictOptions'
|
||||
import { apiOaoaApproveCopy } from '@/api/oa_Initiate'
|
||||
import detailPopup from '@/views/oa_Initiate/detail.vue'
|
||||
import { apiOaoaApproveDetail } from "@/api/oa_Initiate"
|
||||
|
||||
|
||||
const detailRef = ref(null)
|
||||
// 是否显示编辑框
|
||||
const showDetail = ref(false)
|
||||
|
||||
// 查询条件
|
||||
const queryParams = reactive({
|
||||
title: '',
|
||||
status: ''
|
||||
})
|
||||
const typeName = ref('')
|
||||
|
||||
// 选中数据
|
||||
const selectData = ref<any[]>([])
|
||||
|
||||
// 表格选择后回调事件
|
||||
const handleSelectionChange = (val: any[]) => {
|
||||
selectData.value = val.map(({ id }) => id)
|
||||
}
|
||||
|
||||
// 获取字典数据
|
||||
const { dictData } = useDictData('')
|
||||
|
||||
// 分页相关
|
||||
const { pager, getLists, resetParams, resetPage } = usePaging({
|
||||
fetchFun: apiOaoaApproveCopy,
|
||||
params: queryParams
|
||||
})
|
||||
|
||||
const handDetail = async (row: any) => {
|
||||
typeName.value = row.type_name
|
||||
let res = await apiOaoaApproveDetail({ id: row.id })
|
||||
showDetail.value = true
|
||||
await nextTick()
|
||||
detailRef.value?.open()
|
||||
detailRef.value?.setFormData(res)
|
||||
}
|
||||
|
||||
getLists()
|
||||
</script>
|
||||
|
95
src/views/oa_Deal/index.vue
Normal file
95
src/views/oa_Deal/index.vue
Normal file
@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-card class="!border-none mb-4" shadow="never">
|
||||
<el-form class="mb-[-16px]" :model="queryParams" inline>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable class="!flex-1">
|
||||
<el-option label="全部" :value="0" />
|
||||
<el-option label="带我审批" :value="1" />
|
||||
<el-option label="我已审批" :value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="resetPage">查询</el-button>
|
||||
<el-button @click="resetParams">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
|
||||
<div class="mt-4">
|
||||
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="申请人" prop="user_name" show-overflow-tooltip />
|
||||
<el-table-column label="申请时间" prop="create_time" show-overflow-tooltip />
|
||||
<el-table-column label="审批类型" prop="type_name" show-overflow-tooltip />
|
||||
<el-table-column label="所属部门" prop="dept_name" show-overflow-tooltip />
|
||||
<el-table-column label="当前审批人" prop="check_admin_users" show-overflow-tooltip />
|
||||
<el-table-column label="审批状态" prop="check_status_text" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="handDetail(row)">
|
||||
详情
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="flex mt-4 justify-end">
|
||||
<pagination v-model="pager" @change="getLists" />
|
||||
</div>
|
||||
</el-card>
|
||||
<detailPopup v-if="showDetail" ref="detailRef" @success="showDetail = false, getLists()"
|
||||
@close="showDetail = false, getLists()" :typeName="typeName" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="oaSealCateLists">
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import { useDictData } from '@/hooks/useDictOptions'
|
||||
import { apiOaoaApprovelst } from '@/api/oa_Initiate'
|
||||
import detailPopup from '@/views/oa_Initiate/detail.vue'
|
||||
import { apiOaoaApproveDetail } from "@/api/oa_Initiate"
|
||||
|
||||
const detailRef = ref(null)
|
||||
// 是否显示编辑框
|
||||
const showDetail = ref(false)
|
||||
const typeName = ref('')
|
||||
|
||||
|
||||
// 查询条件
|
||||
const queryParams = reactive({
|
||||
title: '',
|
||||
status: ''
|
||||
})
|
||||
|
||||
// 选中数据
|
||||
const selectData = ref<any[]>([])
|
||||
|
||||
// 表格选择后回调事件
|
||||
const handleSelectionChange = (val: any[]) => {
|
||||
selectData.value = val.map(({ id }) => id)
|
||||
}
|
||||
|
||||
// 获取字典数据
|
||||
const { dictData } = useDictData('')
|
||||
|
||||
// 分页相关
|
||||
const { pager, getLists, resetParams, resetPage } = usePaging({
|
||||
fetchFun: apiOaoaApprovelst,
|
||||
params: queryParams
|
||||
})
|
||||
|
||||
const handDetail = async (row: any) => {
|
||||
typeName.value = row.type_name
|
||||
let res = await apiOaoaApproveDetail({ id: row.id })
|
||||
showDetail.value = true
|
||||
await nextTick()
|
||||
detailRef.value?.open()
|
||||
detailRef.value?.setFormData(res)
|
||||
}
|
||||
|
||||
|
||||
|
||||
getLists()
|
||||
</script>
|
||||
|
318
src/views/oa_Initiate/detail.vue
Normal file
318
src/views/oa_Initiate/detail.vue
Normal file
@ -0,0 +1,318 @@
|
||||
<template>
|
||||
<div class="detail-popup">
|
||||
<popup ref="popupRef" :showFootBtn="false" title="审批详情" :async="true" width="60vw" @close='hdClose'>
|
||||
|
||||
<el-card v-if="isGenerateForm">
|
||||
<template #header>审批内容</template>
|
||||
<el-descriptions :column="3" border>
|
||||
<el-descriptions-item v-for="(item, value) in fromValue" :label="item.label" label-align="left"
|
||||
align="left">
|
||||
{{ item.text || item.value }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions :column="1" border v-if='formData.extends?.annex'>
|
||||
<el-descriptions-item label="附件" label-align="left" align="left">
|
||||
<annexLink :annex='formData.extends.annex'></annexLink>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
|
||||
<el-card v-else>
|
||||
<template #header>审批内容</template>
|
||||
<el-descriptions :column="3" border>
|
||||
<el-descriptions-item v-for="(item, value) in fromValue" :label="item" label-align="left" align="left">
|
||||
{{ formData.extends[value] }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions :column="1" border v-if='formData.extends?.annex'>
|
||||
<el-descriptions-item label="附件" label-align="left" align="left">
|
||||
<annexLink :annex='formData.extends.annex'></annexLink>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<template #header>审批流程</template>
|
||||
<el-descriptions :column="3" border>
|
||||
<el-descriptions-item label="审批状态" label-align="left" align="left">
|
||||
{{ formData.check_status_text }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="当前审核人" label-align="left" align="left">
|
||||
{{ formData.check_admin_users || "审批结束" }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="抄送人" label-align="left" align="left">
|
||||
{{ formData.copy_users }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions :column="1" border>
|
||||
<el-descriptions-item label="审批流程" label-align="left" align="left">
|
||||
<el-steps class="mb-4" style="max-width: 50vw" :space="200" :active="findActive() + 2" simple>
|
||||
<el-step :icon="Clock"
|
||||
:title="formData.record[formData.record.length - 1].check_user_name + '创建'" />
|
||||
<el-step :icon="Clock" :title="flowTypeToText(item.flow_type, item)"
|
||||
v-for="item in formData.steps" />
|
||||
</el-steps>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="审批记录" label-align="left" align="left">
|
||||
<p v-for="item in formData.record">
|
||||
<span>{{ item.check_user_name + item.status_text }} </span>了申请
|
||||
{{ item.check_time }}
|
||||
<span>
|
||||
操作意见:
|
||||
{{ item.content }}
|
||||
</span>
|
||||
</p>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="审批节点" label-align="left" align="left"
|
||||
v-if="formData.flow_info.check_type == 2 && formData.check_status != 3 && formData.check_status != 2 && formData.admin_id != userStore.id && showTextarea()">
|
||||
<div class="flex" style="position: relative;">
|
||||
<el-radio-group v-model="form.check_node">
|
||||
<el-radio :label="1">审批结束</el-radio>
|
||||
<el-radio :label="2">下一审批人</el-radio>
|
||||
</el-radio-group>
|
||||
<div class="w-280[px]" style="position: absolute;left:250px">
|
||||
<el-input v-show="form.check_node == 2" v-model="form.check_admin_names"
|
||||
placeholder="点击选择下一审批人" clearable readonly @click="userclick" />
|
||||
</div>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="审批意见" label-align="left" align="left"
|
||||
v-if="showTextarea() && formData.admin_id != userStore.id">
|
||||
<el-input type="textarea" v-model="form.content"></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="操作" label-align="left" align="left" v-if="showTextarea()">
|
||||
<el-button type="primary" @click="form.check = 1, handCheck()"
|
||||
v-if="formData.admin_id != userStore.id">
|
||||
通过
|
||||
</el-button>
|
||||
<el-button @click="form.check = 2, handCheck()"
|
||||
v-if="formData.admin_id != userStore.id && formData.flow_info.check_type != 3">
|
||||
拒绝
|
||||
</el-button>
|
||||
<el-button @click="form.check = 2, handCheck()"
|
||||
v-if="formData.admin_id != userStore.id && formData.flow_info.check_type == 3">
|
||||
回退
|
||||
</el-button>
|
||||
<el-button type="info" @click="showBackDialog = true" v-if="formData.admin_id == userStore.id">
|
||||
撤回
|
||||
</el-button>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="操作" label-align="left" align="left"
|
||||
v-if="formData.check_status == 3 && formData.record[formData.record.length - 1].check_user_id == userStore.id">
|
||||
<el-button type="info" @click="reEdit">
|
||||
重新编辑
|
||||
</el-button>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
<div v-if="showPerDialog">
|
||||
<personnelselector ref="personnel" @confirm="submituser" type="1">
|
||||
</personnelselector>
|
||||
</div>
|
||||
<el-dialog v-model="showBackDialog" title="撤回审批" width="550px">
|
||||
<el-form-item label="撤回原因">
|
||||
<el-input v-model="form.content" type="textarea"> </el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="">
|
||||
<el-button type="primary" @click="backFn">撤回</el-button>
|
||||
<el-button @click="showBackDialog = false">取消</el-button>
|
||||
</el-form-item>
|
||||
</el-dialog>
|
||||
</popup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="customdetail">
|
||||
import annexLink from './../../components/annexLink/index.vue'
|
||||
import Popup from '@/components/popup/index.vue'
|
||||
import { apiOaoaApproveCheck } from "@/api/oa_initiate"
|
||||
import useUserStore from "@/stores/modules/user";
|
||||
import { Clock } from '@element-plus/icons-vue'
|
||||
import feedback from './../../utils/feedback'
|
||||
import { ref, reactive } from "vue"
|
||||
import qja from './form/jq/qja.js'
|
||||
import cca from './form/jq/cca.js'
|
||||
import wca from './form/jq/wca.js'
|
||||
import jba from './form/jq/jba.js'
|
||||
import hysyda from './form/xz/hysyda.js'
|
||||
import gwlza from './form/xz/gwlza.js'
|
||||
import wpwxa from './form/xz/wpwxa.js'
|
||||
import zzjya from './form/xz/zzjya.js'
|
||||
import yza from './form/xz/yza.js'
|
||||
import yca from './form/xz/yca.js'
|
||||
import ycgha from './form/xz/ycgha.js'
|
||||
import jka from './form/cw/jka.js'
|
||||
import fka from './form/cw/fka.js'
|
||||
import jla from './form/cw/jla.js'
|
||||
import cga from './form/cw/cga.js'
|
||||
import hdjfa from './form/cw/hdjfa.js'
|
||||
import rza from './form/rs/rza.js'
|
||||
import zza from './form/rs/zza.js'
|
||||
import lza from './form/rs/lza.js'
|
||||
import zga from './form/rs/zga.js'
|
||||
import zpxqa from './form/rs/zpxqa.js'
|
||||
import tyspa from './form/qt/tyspa.js'
|
||||
let props = defineProps({
|
||||
typeName: {
|
||||
type: String,
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['close', 'reEdit'])
|
||||
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||
const showPerDialog = ref(false);
|
||||
const personnel = ref(null);
|
||||
const userStore = useUserStore().userInfo;
|
||||
const showBackDialog = ref(false)
|
||||
const isGenerateForm = ref(false)
|
||||
|
||||
let fromValue = ref({})
|
||||
const getFormValue = () => {
|
||||
if (props.typeName == '请假') fromValue.value = qja;
|
||||
else if (props.typeName == '出差') fromValue.value = cca;
|
||||
else if (props.typeName == '外出') fromValue.value = wca;
|
||||
else if (props.typeName == '加班') fromValue.value = jba;
|
||||
else if (props.typeName == '会议室预定') fromValue.value = hysyda;
|
||||
else if (props.typeName == '公文流转') fromValue.value = gwlza;
|
||||
else if (props.typeName == '物品维修') fromValue.value = wpwxa;
|
||||
else if (props.typeName == '资质借用') fromValue.value = zzjya;
|
||||
else if (props.typeName == '用章') fromValue.value = yza;
|
||||
else if (props.typeName == '用车') fromValue.value = yca;
|
||||
else if (props.typeName == '用车归还') fromValue.value = ycgha;
|
||||
else if (props.typeName == '借款') fromValue.value = jka;
|
||||
else if (props.typeName == '付款') fromValue.value = fka;
|
||||
else if (props.typeName == '奖励') fromValue.value = jla;
|
||||
else if (props.typeName == '采购') fromValue.value = cga;
|
||||
else if (props.typeName == '活动经费') fromValue.value = hdjfa;
|
||||
else if (props.typeName == '入职') fromValue.value = rza;
|
||||
else if (props.typeName == '转正') fromValue.value = zza;
|
||||
else if (props.typeName == '离职') fromValue.value = lza;
|
||||
else if (props.typeName == '转岗') fromValue.value = zga;
|
||||
else if (props.typeName == '招聘需求') fromValue.value = zpxqa;
|
||||
else if (props.typeName == '通用审批') fromValue.value = tyspa;
|
||||
else {
|
||||
fromValue.value = formData.extends
|
||||
isGenerateForm.value = true
|
||||
}
|
||||
console.log(fromValue.value)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
id: 0,
|
||||
extends: {}
|
||||
})
|
||||
|
||||
// 获取详情
|
||||
const setFormData = async (data: Record<any, any>) => {
|
||||
for (const key in data) {
|
||||
if (data[key] != null && data[key] != undefined) {
|
||||
//@ts-ignore
|
||||
formData[key] = data[key]
|
||||
}
|
||||
}
|
||||
getFormValue()
|
||||
|
||||
}
|
||||
|
||||
|
||||
const form = reactive({
|
||||
"id": formData.id,
|
||||
"check": '',
|
||||
"content": "",
|
||||
"check_node": 1,
|
||||
"check_admin_ids": '',
|
||||
check_admin_names: ""
|
||||
})
|
||||
|
||||
|
||||
const backFn = () => {
|
||||
if (!form.content) return feedback.msgError("请填写撤回原因");
|
||||
form.check = 3
|
||||
handCheck()
|
||||
}
|
||||
const userclick = async () => {
|
||||
showPerDialog.value = true;
|
||||
await nextTick();
|
||||
personnel.value.open();
|
||||
};
|
||||
|
||||
const submituser = (e) => {
|
||||
form.check_admin_names = e.name;
|
||||
form.check_admin_ids = e.id;
|
||||
showPerDialog.value = false;
|
||||
};
|
||||
|
||||
|
||||
//打开弹窗
|
||||
const open = () => {
|
||||
popupRef.value?.open()
|
||||
}
|
||||
|
||||
const flowTypeToText = (type, item) => {
|
||||
if (type == 0) return item.user_id_info[0].name;
|
||||
if (type == 1) return "部门负责人";
|
||||
if (type == 2) return "或签";
|
||||
if (type == 3) return "会签";
|
||||
if (type == 4) return item.user_id_info[0].name;
|
||||
}
|
||||
|
||||
const findActive = () => {
|
||||
let index = formData.steps.findIndex(item => { return item.sort == formData.check_step_sort })
|
||||
return index
|
||||
}
|
||||
|
||||
// 关闭回调
|
||||
const handleClose = () => {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
const hdClose = () => {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
|
||||
// 审批
|
||||
const handCheck = async () => {
|
||||
if (form.check == 2 && !form.content) return feedback.msgError("请填写审批意见")
|
||||
if (formData.check_admin_ids && formData.record[formData.record.length - 1].check_user_id == form.check_admin_ids) {
|
||||
return feedback.msgError("下一级审批人不能是发起审批人")
|
||||
}
|
||||
if (formData.flow_info.check_type != 2) delete form.check_node;
|
||||
form.id = formData.id
|
||||
const res = await apiOaoaApproveCheck({ ...form })
|
||||
handleClose()
|
||||
}
|
||||
|
||||
// 显示
|
||||
const showActionList = reactive([4, 3, 2])
|
||||
const showTextarea = () => {
|
||||
if (showActionList.includes(formData.check_status)) return false;
|
||||
if (formData.admin_id == userStore.id) return true;
|
||||
if (formData?.check_admin_ids.length > 1) {
|
||||
if (formData.steps[findActive()].check_list.map(item => item.check_user_id).includes(userStore.id)) return false;
|
||||
else return (formData?.check_admin_ids.split(',').map(Number).includes(userStore.id)); // 判断是否是当前用户
|
||||
} else {
|
||||
return (formData?.check_admin_ids == userStore.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//重新编辑
|
||||
|
||||
const reEdit = () => {
|
||||
emit('reEdit', { extends: formData.extends, typeName: props.typeName, cate: formData.flow_info.flow_cate })
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
setFormData,
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-step__icon) {
|
||||
margin-top: 10px !important;
|
||||
}
|
||||
</style>
|
132
src/views/oa_Initiate/edit.vue
Normal file
132
src/views/oa_Initiate/edit.vue
Normal file
@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<div class="edit-popup">
|
||||
<popup ref="popupRef" :title="popupTitle" :async="true" width="60vw" @confirm="handleSubmit" @close="handleClose">
|
||||
<el-card>
|
||||
<template #header>
|
||||
审批内容
|
||||
</template>
|
||||
<qj :formData=formData.extends ref="forms" v-if="type == '请假'"></qj>
|
||||
<cc ref="forms" :formData=formData.extends v-else-if="type == '出差'"></cc>
|
||||
<wc ref="forms" :formData=formData.extends v-else-if="type == '外出'"></wc>
|
||||
<jb ref="forms" :formData=formData.extends v-else-if="type == '加班'"></jb>
|
||||
<hysyd ref="forms" :formData=formData.extends v-else-if="type == '会议室预定'"></hysyd>
|
||||
<gwlz ref="forms" :formData=formData.extends v-else-if="type == '公文流转'"></gwlz>
|
||||
<wpwx ref="forms" :formData=formData.extends v-else-if="type == '物品维修'"></wpwx>
|
||||
<zzjy ref="forms" :formData=formData.extends v-else-if="type == '资质借用'"></zzjy>
|
||||
<yz ref="forms" :formData=formData.extends v-else-if="type == '用章'"></yz>
|
||||
<yc ref="forms" :formData=formData.extends v-else-if="type == '用车'"></yc>
|
||||
<ycgh ref="forms" :formData=formData.extends v-else-if="type == '用车归还'"></ycgh>
|
||||
<jk ref="forms" :formData=formData.extends v-else-if="type == '借款'"></jk>
|
||||
<fk ref="forms" :formData=formData.extends v-else-if="type == '付款'"></fk>
|
||||
<jl ref="forms" :formData=formData.extends v-else-if="type == '奖励'"></jl>
|
||||
<cg ref="forms" :formData=formData.extends v-else-if="type == '采购'"></cg>
|
||||
<hdjf ref="forms" :formData=formData.extends v-else-if="type == '活动经费'"></hdjf>
|
||||
<rz ref="forms" :formData=formData.extends v-else-if="type == '入职'"></rz>
|
||||
<zz ref="forms" :formData=formData.extends v-else-if="type == '转正'"></zz>
|
||||
<lz ref="forms" :formData=formData.extends v-else-if="type == '离职'"></lz>
|
||||
<zg ref="forms" :formData=formData.extends v-else-if="type == '转岗'"></zg>
|
||||
<zpxq ref="forms" :formData=formData.extends v-else-if="type == '招聘需求'"></zpxq>
|
||||
<tysp ref="forms" :formData=formData.extends v-else-if="type == '通用审批'"></tysp>
|
||||
<generateForm :config="formData.data" :formData="formData.extends" v-else></generateForm>
|
||||
</el-card>
|
||||
<oaFlow :form-data="formData" :flow_cate="formData.id"></oaFlow>
|
||||
</popup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="oaFlowTypeEdit">
|
||||
import generateForm from './../../components/generateForm/index.vue'
|
||||
import Popup from "@/components/popup/index.vue";
|
||||
import { apiOaoaApproveAdd } from "@/api/oa_Initiate"
|
||||
import qj from './form/jq/qj.vue'
|
||||
import cc from './form/jq/cc.vue'
|
||||
import wc from './form/jq/wc.vue'
|
||||
import jb from './form/jq/jb.vue'
|
||||
import hysyd from './form/xz/hysyd.vue'
|
||||
import gwlz from './form/xz/gwlz.vue'
|
||||
import wpwx from './form/xz/wpwx.vue'
|
||||
import zzjy from './form/xz/zzjy.vue'
|
||||
import yz from './form/xz/yz.vue'
|
||||
import yc from './form/xz/yc.vue'
|
||||
import ycgh from './form/xz/ycgh.vue'
|
||||
import jk from './form/cw/jk.vue'
|
||||
import fk from './form/cw/fk.vue'
|
||||
import jl from './form/cw/jl.vue'
|
||||
import cg from './form/cw/cg.vue'
|
||||
import hdjf from './form/cw/hdjf.vue'
|
||||
import rz from './form/rs/rz.vue'
|
||||
import zz from './form/rs/zz.vue'
|
||||
import lz from './form/rs/lz.vue'
|
||||
import zg from './form/rs/zg.vue'
|
||||
import zpxq from './form/rs/zpxq.vue'
|
||||
import tysp from './form/qt/tysp.vue'
|
||||
|
||||
defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
}
|
||||
})
|
||||
|
||||
const forms = ref('')
|
||||
const emit = defineEmits(["success", "close"]);
|
||||
const popupRef = shallowRef<InstanceType<typeof Popup>>();
|
||||
const mode = ref("add");
|
||||
|
||||
// 弹窗标题
|
||||
const popupTitle = computed(() => {
|
||||
return "新增审批"
|
||||
});
|
||||
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
id: 0,
|
||||
data: [],
|
||||
extends: {}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
// 获取详情
|
||||
const setFormData = async (data: Record<any, any>) => {
|
||||
formData.data = data.data;
|
||||
formData.id = data.id;
|
||||
};
|
||||
|
||||
// 获取详情
|
||||
const setExtend = async (data: Record<any, any>) => {
|
||||
formData.extends = data
|
||||
};
|
||||
|
||||
|
||||
|
||||
// 提交按钮
|
||||
const handleSubmit = async () => {
|
||||
if (forms.value) {
|
||||
await forms.value?.check();
|
||||
}
|
||||
const data = { ...formData };
|
||||
await apiOaoaApproveAdd(data)
|
||||
popupRef.value?.close();
|
||||
emit("success");
|
||||
|
||||
|
||||
};
|
||||
|
||||
//打开弹窗
|
||||
const open = (type = "add") => {
|
||||
mode.value = type;
|
||||
popupRef.value?.open();
|
||||
};
|
||||
|
||||
// 关闭回调
|
||||
const handleClose = () => {
|
||||
emit("close");
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
setFormData,
|
||||
setExtend
|
||||
});
|
||||
</script>
|
111
src/views/oa_Initiate/form/cw/cg.vue
Normal file
111
src/views/oa_Initiate/form/cw/cg.vue
Normal file
@ -0,0 +1,111 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="物品名称" prop="wpmc">
|
||||
<el-input v-model="formData.wpmc" clearable placeholder="请输入物品名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="期望交互日期" prop="kssj">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.kssj" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择期望交互日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item label="采购数量" prop="chsl">
|
||||
<el-input v-model="formData.chsl" clearable placeholder="请输入采购数量" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item label="采购金额" prop="chje">
|
||||
<el-input v-model="formData.chje" clearable placeholder="请输入采购金额" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item label="采购事由" prop="jlsy">
|
||||
<el-input v-model="formData.jlsy" clearable placeholder="请输入采购事由" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="formData.bz" clearable placeholder="请输入备注" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="附件">
|
||||
<uploadAnnex :form-data="formData"></uploadAnnex>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const qjlxList = reactive(['会议室一', '会议室二', '会议室三'])
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
|
||||
})
|
||||
const formRef = ref(null)
|
||||
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
wpmc: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
chsl: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
|
||||
|
||||
jlsy: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
chje: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
kssj: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
|
||||
|
||||
|
||||
jssj: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
jbsy: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
})
|
||||
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
</script>
|
9
src/views/oa_Initiate/form/cw/cga.js
Normal file
9
src/views/oa_Initiate/form/cw/cga.js
Normal file
@ -0,0 +1,9 @@
|
||||
const cga = {
|
||||
wpmc: "物品名称",
|
||||
kssj: "期望交互日期",
|
||||
chsl: "采购数量",
|
||||
chje: "采购金额",
|
||||
jlsy: "采购事由",
|
||||
bz: "备注",
|
||||
}
|
||||
export default cga
|
100
src/views/oa_Initiate/form/cw/fk.vue
Normal file
100
src/views/oa_Initiate/form/cw/fk.vue
Normal file
@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="付款金额" prop="jkje">
|
||||
<el-input v-model="formData.wjmc" clearable placeholder="请输入付款金额" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="付款方式" prop="jjlx">
|
||||
<el-select v-model="formData.jjlx" placeholder="请选择付款方式" class="flex-1">
|
||||
<el-option :label="item" :value="item" v-for="(item, index) in qjlxList" :key="index">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="付款日期" prop="lwrq">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.lwrq" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择付款日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="收款人全称" prop="jyr">
|
||||
<el-input v-model="formData.jyr" clearable placeholder="请输入收款人全称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item label="银行账号" prop="yhzh">
|
||||
<el-input v-model="formData.yhzh" clearable placeholder="请输入银行账号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item label="开户行" prop="khh">
|
||||
<el-input v-model="formData.yhzh" clearable placeholder="请输入开户行" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item label="付款事由" prop="bz">
|
||||
<el-input v-model="formData.bz" clearable placeholder="请输入付款事由" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="formData.bz1" clearable placeholder="请输入备注" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="附件">
|
||||
<uploadAnnex :form-data="formData"></uploadAnnex>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
|
||||
|
||||
</el-row>
|
||||
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
let list = ['jkje', 'jjlx', 'jyr', 'yhzh', 'khh', "bz", 'lwrq']
|
||||
|
||||
const qjlxList = reactive(['银行卡', '现金', '汇票', '电汇', '贷记', '支票', '其他'])
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
|
||||
})
|
||||
const formRef = ref(null)
|
||||
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
})
|
||||
|
||||
const setRules = () => {
|
||||
list.forEach(item => {
|
||||
formRules[item] = [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
setRules()
|
||||
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
|
||||
</script>
|
11
src/views/oa_Initiate/form/cw/fka.js
Normal file
11
src/views/oa_Initiate/form/cw/fka.js
Normal file
@ -0,0 +1,11 @@
|
||||
const fka = {
|
||||
wjmc: "付款金额",
|
||||
jjlx: "付款方式",
|
||||
lwrq: "付款日期",
|
||||
jyr: "收款人全称",
|
||||
yhzh: "银行账号",
|
||||
yhzh: "开户行",
|
||||
bz: "付款事由",
|
||||
bz1: "备注",
|
||||
}
|
||||
export default fka
|
118
src/views/oa_Initiate/form/cw/hdjf.vue
Normal file
118
src/views/oa_Initiate/form/cw/hdjf.vue
Normal file
@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="活动名称" prop="jlje">
|
||||
<el-input v-model="formData.jlje" clearable placeholder="请输入活动名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="活动预算" prop="jlje1">
|
||||
<el-input v-model="formData.jlje" clearable placeholder="请输入活动预算" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="活动说明" prop="hdsm">
|
||||
<el-input v-model="formData.hdsm" clearable placeholder="请输入活动说明" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item label="开始时间" prop="kssj">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.kssj" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="结束时间" prop="jssj">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.jssj" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择结束时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="formData.bz" clearable placeholder="请输入备注" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="附件">
|
||||
<uploadAnnex :form-data="formData"></uploadAnnex>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const qjlxList = reactive(['会议室一', '会议室二', '会议室三'])
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
|
||||
})
|
||||
const formRef = ref(null)
|
||||
|
||||
const checkDate = (rule: any, value: any, callback: any) => {
|
||||
if (new Date(props.formData.jssj) < new Date(props.formData.kssj)) {
|
||||
callback(new Error('结束时间不能早于开始时间'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
jlje: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
jlje1: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
hdsm: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
|
||||
kssj: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
jssj: [
|
||||
{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
},
|
||||
{
|
||||
validator: checkDate,
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
jbsy: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
})
|
||||
|
||||
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
</script>
|
10
src/views/oa_Initiate/form/cw/hdjfa.js
Normal file
10
src/views/oa_Initiate/form/cw/hdjfa.js
Normal file
@ -0,0 +1,10 @@
|
||||
const hdjfa = {
|
||||
jlje: "活动名称",
|
||||
jlje: "活动预算",
|
||||
hdsm: "活动说明",
|
||||
kssj: "开始时间",
|
||||
jssj: "结束时间",
|
||||
bz: "备注",
|
||||
|
||||
}
|
||||
export default hdjfa
|
112
src/views/oa_Initiate/form/cw/jk.vue
Normal file
112
src/views/oa_Initiate/form/cw/jk.vue
Normal file
@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="借款金额" prop="wjmc">
|
||||
<el-input v-model="formData.wjmc" clearable placeholder="请输入借款金额" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="借款类型" prop="jjlx">
|
||||
<el-select v-model="formData.jjlx" placeholder="请选择借款类型" class="flex-1">
|
||||
<el-option :label="item" :value="item" v-for="(item, index) in qjlxList" :key="index">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="申请日期" prop="lwrq">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.lwrq" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择申请日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="借款人" prop="jyr">
|
||||
<el-input v-model="formData.jyr" clearable placeholder="请输入借用人" @click="userclick('jyr')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item label="银行账号" prop="yhzh">
|
||||
<el-input v-model="formData.yhzh" clearable placeholder="请输入银行账号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item label="开户行" prop="khh">
|
||||
<el-input v-model="formData.khh" clearable placeholder="请输入开户行" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item label="借款事由" prop="bz">
|
||||
<el-input v-model="formData.bz" clearable placeholder="请输入借款事由" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="formData.bz1" clearable placeholder="请输入备注" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div v-if="showPerDialog">
|
||||
<personnelselector ref="personnel" @confirm="submituser" type="1">
|
||||
</personnelselector>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
let list = ['wjmc', 'jkje', 'jjlx', 'jyr', 'yhzh', 'khh', "bz", 'lwrq']
|
||||
|
||||
const qjlxList = reactive(['差旅费', '办公费', '招待费', '交通费', '通讯费', '采购付款', '其他'])
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
|
||||
})
|
||||
const formRef = ref(null)
|
||||
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
})
|
||||
|
||||
const setRules = () => {
|
||||
list.forEach(item => {
|
||||
formRules[item] = [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
setRules()
|
||||
|
||||
|
||||
|
||||
const showPerDialog = ref(false)
|
||||
const personnel = ref(null)
|
||||
|
||||
let value
|
||||
const userclick = async (val) => {
|
||||
showPerDialog.value = true
|
||||
value = val
|
||||
await nextTick()
|
||||
personnel.value.open()
|
||||
}
|
||||
const submituser = (e) => {
|
||||
props.formData[value] = e.name
|
||||
props.formData[value + "_id"] = e.id
|
||||
showPerDialog.value = false
|
||||
}
|
||||
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
</script>
|
12
src/views/oa_Initiate/form/cw/jka.js
Normal file
12
src/views/oa_Initiate/form/cw/jka.js
Normal file
@ -0,0 +1,12 @@
|
||||
const jka = {
|
||||
wjmc: "借款金额",
|
||||
jjlx: "借款类型",
|
||||
lwrq: "申请日期",
|
||||
jyr: "借款人",
|
||||
yhzh: "银行账号",
|
||||
khh: "开户行",
|
||||
bz: "借款事由",
|
||||
bz1: "备注",
|
||||
|
||||
}
|
||||
export default jka
|
86
src/views/oa_Initiate/form/cw/jl.vue
Normal file
86
src/views/oa_Initiate/form/cw/jl.vue
Normal file
@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="奖励金额" prop="jlje">
|
||||
<el-input v-model="formData.jlje" clearable placeholder="请输入奖励金额" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="奖励日期" prop="kssj">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.kssj" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择奖励日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item label="奖励事由" prop="jlsy">
|
||||
<el-input v-model="formData.jlsy" clearable placeholder="请输入奖励事由" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="formData.bz" clearable placeholder="请输入备注" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="附件">
|
||||
<uploadAnnex :form-data="formData"></uploadAnnex>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
|
||||
})
|
||||
const qjlxList = reactive(['会议室一', '会议室二', '会议室三'])
|
||||
const formRef = ref(null)
|
||||
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
jlje: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
jlsy: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
|
||||
|
||||
kssj: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
jssj: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
jbsy: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
})
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
|
||||
</script>
|
7
src/views/oa_Initiate/form/cw/jla.js
Normal file
7
src/views/oa_Initiate/form/cw/jla.js
Normal file
@ -0,0 +1,7 @@
|
||||
const jla = {
|
||||
jlje: "奖励金额",
|
||||
kssj: "奖励日期",
|
||||
jlsy: "奖励事由",
|
||||
bz: "备注",
|
||||
}
|
||||
export default jla
|
103
src/views/oa_Initiate/form/jq/cc.vue
Normal file
103
src/views/oa_Initiate/form/jq/cc.vue
Normal file
@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="开始时间" prop="kssj">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.kssj" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间" @change="calcDay">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="结束时间" prop="jssj">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.jssj" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择结束时间" @change="calcDay">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="出差天数">
|
||||
<el-input v-model="formData.qjts" clearable readonly placeholder="系统自动计算" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="出差事由" prop="ccsy">
|
||||
<el-input v-model="formData.ccsy" clearable placeholder="请输入出差事由" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="附件">
|
||||
<uploadAnnex :form-data="formData"></uploadAnnex>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const qjlxList = reactive(['事假', '年假', '调休假', '病假', '婚假', '产假', '陪产假', '其他'])
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
|
||||
})
|
||||
const formRef = ref(null)
|
||||
|
||||
|
||||
const checkDate = (rule: any, value: any, callback: any) => {
|
||||
if (new Date(props.formData.jssj) < new Date(props.formData.kssj)) {
|
||||
callback(new Error('结束时间不能早于开始时间'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
qjlx: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
kssj: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
jssj: [
|
||||
{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
},
|
||||
{
|
||||
validator: checkDate,
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
ccsy: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
})
|
||||
|
||||
const calcDay = () => {
|
||||
const date1 = props.formData.kssj;
|
||||
const date2 = props.formData?.jssj;
|
||||
if (date1 && date2) {
|
||||
const timeDiff = new Date(date2).getTime() - new Date(date1).getTime();
|
||||
const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24));
|
||||
props.formData.qjts = daysDiff || 0
|
||||
}
|
||||
}
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
</script>
|
7
src/views/oa_Initiate/form/jq/cca.js
Normal file
7
src/views/oa_Initiate/form/jq/cca.js
Normal file
@ -0,0 +1,7 @@
|
||||
const cca = {
|
||||
kssj: "开始时间",
|
||||
jssj: "结束时间",
|
||||
qjts: "出差天数",
|
||||
ccsy: "出差事由",
|
||||
}
|
||||
export default cca
|
105
src/views/oa_Initiate/form/jq/jb.vue
Normal file
105
src/views/oa_Initiate/form/jq/jb.vue
Normal file
@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="开始时间" prop="kssj">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.kssj" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间" @change="calcDay">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="结束时间" prop="jssj">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.jssj" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择结束时间" @change="calcDay">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="加班天数">
|
||||
<el-input v-model="formData.qjts" clearable placeholder="系统自动计算" readonly />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="加班事由" prop="jbsy">
|
||||
<el-input v-model="formData.jbsy" clearable placeholder="请输入加班事由" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="附件">
|
||||
<uploadAnnex :form-data="formData"></uploadAnnex>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const qjlxList = reactive(['事假', '年假', '调休假', '病假', '婚假', '产假', '陪产假', '其他'])
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
|
||||
})
|
||||
const formRef = ref(null)
|
||||
|
||||
const checkDate = (rule: any, value: any, callback: any) => {
|
||||
if (new Date(props.formData.jssj) < new Date(props.formData.kssj)) {
|
||||
callback(new Error('结束时间不能早于开始时间'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
qjlx: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
kssj: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
jssj: [
|
||||
{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
},
|
||||
{
|
||||
validator: checkDate,
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
jbsy: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
})
|
||||
|
||||
|
||||
const calcDay = () => {
|
||||
const date1 = props.formData.kssj;
|
||||
const date2 = props.formData?.jssj;
|
||||
if (date1 && date2) {
|
||||
const timeDiff = new Date(date2).getTime() - new Date(date1).getTime();
|
||||
const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24));
|
||||
props.formData.qjts = daysDiff || 0
|
||||
}
|
||||
}
|
||||
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
</script>
|
7
src/views/oa_Initiate/form/jq/jba.js
Normal file
7
src/views/oa_Initiate/form/jq/jba.js
Normal file
@ -0,0 +1,7 @@
|
||||
const jba = {
|
||||
kssj: "开始时间",
|
||||
jssj: "结束时间",
|
||||
qjts: "加班天数",
|
||||
jbsy: "加班事由",
|
||||
}
|
||||
export default jba
|
115
src/views/oa_Initiate/form/jq/qj.vue
Normal file
115
src/views/oa_Initiate/form/jq/qj.vue
Normal file
@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="请假类型" prop="qjlx">
|
||||
<el-select v-model="formData.qjlx" placeholder="请选择请假类型" class="flex-1">
|
||||
<el-option :label="item" :value="item" v-for="(item, index) in qjlxList" :key="index">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="开始时间" prop="kssj">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.kssj" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间" @change="calcDay">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="结束时间" prop="jssj">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.jssj" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择结束时间" @change="calcDay">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="请假天数">
|
||||
<el-input v-model="formData.qjts" clearable placeholder="系统自动计算" readonly />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="请假事由" prop="qjsy">
|
||||
<el-input v-model="formData.qjsy" clearable placeholder="请输入请假事由" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="附件">
|
||||
<uploadAnnex :form-data="formData"></uploadAnnex>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
|
||||
})
|
||||
|
||||
|
||||
const qjlxList = reactive(['事假', '年假', '调休假', '病假', '婚假', '产假', '陪产假', '其他'])
|
||||
const formRef = ref(null)
|
||||
|
||||
const checkDate = (rule: any, value: any, callback: any) => {
|
||||
if (new Date(props.formData.jssj) < new Date(props.formData.kssj)) {
|
||||
callback(new Error('结束时间不能早于开始时间'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
qjlx: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
kssj: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
jssj: [
|
||||
{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
},
|
||||
{
|
||||
validator: checkDate,
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
qjsy: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
})
|
||||
|
||||
const calcDay = () => {
|
||||
const date1 = props.formData.kssj;
|
||||
const date2 = props.formData?.jssj;
|
||||
if (date1 && date2) {
|
||||
const timeDiff = new Date(date2).getTime() - new Date(date1).getTime();
|
||||
const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24));
|
||||
props.formData.qjts = daysDiff || 0
|
||||
}
|
||||
}
|
||||
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
|
||||
|
||||
</script>
|
8
src/views/oa_Initiate/form/jq/qja.js
Normal file
8
src/views/oa_Initiate/form/jq/qja.js
Normal file
@ -0,0 +1,8 @@
|
||||
const qja = {
|
||||
qjlx: "请假类型",
|
||||
kssj: "开始时间",
|
||||
jssj: "结束时间",
|
||||
qjts: "请假天数",
|
||||
qjsy: "请假事由",
|
||||
}
|
||||
export default qja
|
115
src/views/oa_Initiate/form/jq/wc.vue
Normal file
115
src/views/oa_Initiate/form/jq/wc.vue
Normal file
@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="外出地点" prop="wcdd">
|
||||
<el-input v-model="formData.wcdd" clearable placeholder="请输入外出地点" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="开始时间" prop="kssj">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.kssj" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间" @change="calcDay">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="结束时间" prop="jssj">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.jssj" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择结束时间" @change="calcDay">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="外出天数">
|
||||
<el-input v-model="formData.qjts" clearable readonly placeholder="系统自动计算" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="外出事由" prop="wcsy">
|
||||
<el-input v-model="formData.wcsy" clearable placeholder="请输入外出事由" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="附件">
|
||||
<uploadAnnex :form-data="formData"></uploadAnnex>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const qjlxList = reactive(['事假', '年假', '调休假', '病假', '婚假', '产假', '陪产假', '其他'])
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
|
||||
})
|
||||
const formRef = ref(null)
|
||||
|
||||
const checkDate = (rule: any, value: any, callback: any) => {
|
||||
if (new Date(props.formData.jssj) < new Date(props.formData.kssj)) {
|
||||
callback(new Error('结束时间不能早于开始时间'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
qjlx: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
kssj: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
jssj: [
|
||||
{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
},
|
||||
{
|
||||
validator: checkDate,
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
wcsy: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
|
||||
wcdd: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
|
||||
})
|
||||
|
||||
const calcDay = () => {
|
||||
const date1 = props.formData.kssj;
|
||||
const date2 = props.formData?.jssj;
|
||||
if (date1 && date2) {
|
||||
const timeDiff = new Date(date2).getTime() - new Date(date1).getTime();
|
||||
const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24));
|
||||
props.formData.qjts = daysDiff || 0
|
||||
}
|
||||
}
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
|
||||
</script>
|
8
src/views/oa_Initiate/form/jq/wca.js
Normal file
8
src/views/oa_Initiate/form/jq/wca.js
Normal file
@ -0,0 +1,8 @@
|
||||
const wca = {
|
||||
wcdd: "外出地点",
|
||||
kssj: "开始时间",
|
||||
jssj: "结束时间",
|
||||
qjts: "外出天数",
|
||||
wcsy: "外出事由",
|
||||
}
|
||||
export default wca
|
76
src/views/oa_Initiate/form/qt/tysp.vue
Normal file
76
src/views/oa_Initiate/form/qt/tysp.vue
Normal file
@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="审批内容" prop="jyr">
|
||||
<el-input v-model="formData.jyr" clearable placeholder="请输入审批内容" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="紧急程度" prop="jjlx">
|
||||
<el-select v-model="formData.jjlx" placeholder="请选择紧急程度" class="flex-1">
|
||||
<el-option :label="item" :value="item" v-for="(item, index) in qjlxList" :key="index">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="详细描述" prop="bz1">
|
||||
<el-input v-model="formData.bz1" clearable placeholder="请输入详细描述" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="附件">
|
||||
<uploadAnnex :form-data="formData"></uploadAnnex>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div v-if="showPerDialog">
|
||||
<personnelselector ref="personnel" @confirm="submituser" type="1">
|
||||
</personnelselector>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
let list = ['jyr', 'lwrq', 'wjmc', 'sex', 'rzbm', "drzw", 'lwrq1', 'jjlx', 'bz1']
|
||||
|
||||
const qjlxList = reactive(['普通', '紧急', '特急'])
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
|
||||
})
|
||||
const formRef = ref(null)
|
||||
|
||||
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
})
|
||||
|
||||
const setRules = () => {
|
||||
list.forEach(item => {
|
||||
formRules[item] = [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
setRules()
|
||||
|
||||
|
||||
|
||||
const showPerDialog = ref(false)
|
||||
const personnel = ref(null)
|
||||
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
</script>
|
7
src/views/oa_Initiate/form/qt/tyspa.js
Normal file
7
src/views/oa_Initiate/form/qt/tyspa.js
Normal file
@ -0,0 +1,7 @@
|
||||
const tyspa = {
|
||||
jyr: "审批内容",
|
||||
jjlx: "紧急程度",
|
||||
bz1: "详细描述",
|
||||
|
||||
}
|
||||
export default tyspa
|
140
src/views/oa_Initiate/form/rs/lz.vue
Normal file
140
src/views/oa_Initiate/form/rs/lz.vue
Normal file
@ -0,0 +1,140 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="员工姓名" prop="jyr">
|
||||
<el-input v-model="formData.jyr" clearable placeholder="请输入员工姓名" @click="userclick('jyr')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="入职时间" prop="lwrq">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.lwrq" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择入职时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="所在部门" prop="rzbm">
|
||||
<el-select v-model="formData.rzbm" placeholder="请选择所在部门" class="flex-1">
|
||||
<el-option :label="item.name" :value="item.name" v-for="item in deptList">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="担任职务" prop="drzw">
|
||||
<el-select v-model="formData.drzw" placeholder="请选择担任职务" class="flex-1">
|
||||
<el-option :label="item.name" :value="item.name" v-for="item in zwlist">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item label="申请离职日期" prop="lwrq1">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.lwrq1" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择申请离职日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="预计离职日期" prop="lwrq2">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.lwrq2" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择预计离职日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="离职原因" prop="bz1">
|
||||
<el-input v-model="formData.bz1" clearable placeholder="请输入离职原因" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="附件">
|
||||
<uploadAnnex :form-data="formData"></uploadAnnex>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div v-if="showPerDialog">
|
||||
<personnelselector ref="personnel" @confirm="submituser" type="1">
|
||||
</personnelselector>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { deptLists } from "@/api/org/department";
|
||||
import { jobsLists } from '@/api/org/post'
|
||||
|
||||
let list = ['jyr', 'lwrq', 'wjmc', 'sex', 'rzbm', "drzw", 'lwrq1', 'lwrq2', 'bz1']
|
||||
|
||||
const qjlxList = reactive(['差旅费', '办公费', '招待费', '交通费', '通讯费', '采购付款', '其他'])
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
|
||||
})
|
||||
const formRef = ref(null)
|
||||
|
||||
|
||||
|
||||
const deptList = ref([])
|
||||
const getDeptList = async () => {
|
||||
const res = await deptLists()
|
||||
deptList.value = res.lists
|
||||
}
|
||||
getDeptList()
|
||||
|
||||
|
||||
const zwlist = ref([])
|
||||
const getzwlist = async () => {
|
||||
const res = await jobsLists()
|
||||
zwlist.value = res.lists
|
||||
}
|
||||
getzwlist()
|
||||
|
||||
|
||||
|
||||
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
})
|
||||
|
||||
const setRules = () => {
|
||||
list.forEach(item => {
|
||||
formRules[item] = [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
setRules()
|
||||
|
||||
|
||||
|
||||
const showPerDialog = ref(false)
|
||||
const personnel = ref(null)
|
||||
|
||||
let value
|
||||
const userclick = async (val) => {
|
||||
showPerDialog.value = true
|
||||
value = val
|
||||
await nextTick()
|
||||
personnel.value.open()
|
||||
}
|
||||
const submituser = (e) => {
|
||||
formData[value] = e.name
|
||||
formData[value + "_id"] = e.id
|
||||
showPerDialog.value = false
|
||||
}
|
||||
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
</script>
|
11
src/views/oa_Initiate/form/rs/lza.js
Normal file
11
src/views/oa_Initiate/form/rs/lza.js
Normal file
@ -0,0 +1,11 @@
|
||||
const lza = {
|
||||
jyr: "员工姓名",
|
||||
lwrq: "入职时间",
|
||||
rzbm: "所在部门",
|
||||
drzw: "担任职务",
|
||||
lwrq1: "申请离职日期",
|
||||
lwrq2: "预计离职日期",
|
||||
bz1: "离职原因",
|
||||
|
||||
}
|
||||
export default lza
|
133
src/views/oa_Initiate/form/rs/rz.vue
Normal file
133
src/views/oa_Initiate/form/rs/rz.vue
Normal file
@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="员工姓名" prop="jyr">
|
||||
<el-input v-model="formData.jyr" clearable placeholder="请输入员工姓名" @click="userclick('jyr')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="入职时间" prop="lwrq">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.lwrq" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择入职时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="手机号码" prop="wjmc">
|
||||
<el-input v-model="formData.wjmc" clearable placeholder="请输入手机号码" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="性别" prop="sex">
|
||||
<el-select v-model="formData.sex" placeholder="请选择性别" class="flex-1">
|
||||
<el-option label="男" value="男"></el-option>
|
||||
<el-option label="女" value="女"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="入职部门" prop="rzbm">
|
||||
<el-select v-model="formData.rzbm" placeholder="请选择入职部门" class="flex-1">
|
||||
<el-option :label="item.name" :value="item.name" v-for="item in deptList">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="担任职务" prop="drzw">
|
||||
<el-select v-model="formData.drzw" placeholder="请选择担任职务" class="flex-1">
|
||||
<el-option :label="item.name" :value="item.name" v-for="item in zwlist">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="formData.bz1" clearable placeholder="请输入备注" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div v-if="showPerDialog">
|
||||
<personnelselector ref="personnel" @confirm="submituser" type="1">
|
||||
</personnelselector>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { deptLists } from "@/api/org/department";
|
||||
import { jobsLists } from '@/api/org/post'
|
||||
|
||||
let list = ['jyr', 'lwrq', 'wjmc', 'sex', 'rzbm', "drzw"]
|
||||
|
||||
const qjlxList = reactive(['差旅费', '办公费', '招待费', '交通费', '通讯费', '采购付款', '其他'])
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
|
||||
})
|
||||
const formRef = ref(null)
|
||||
|
||||
|
||||
|
||||
const deptList = ref([])
|
||||
const getDeptList = async () => {
|
||||
const res = await deptLists()
|
||||
deptList.value = res.lists
|
||||
}
|
||||
getDeptList()
|
||||
|
||||
|
||||
const zwlist = ref([])
|
||||
const getzwlist = async () => {
|
||||
const res = await jobsLists()
|
||||
zwlist.value = res.lists
|
||||
}
|
||||
getzwlist()
|
||||
|
||||
|
||||
|
||||
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
})
|
||||
|
||||
const setRules = () => {
|
||||
list.forEach(item => {
|
||||
formRules[item] = [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
setRules()
|
||||
|
||||
|
||||
|
||||
const showPerDialog = ref(false)
|
||||
const personnel = ref(null)
|
||||
|
||||
let value
|
||||
const userclick = async (val) => {
|
||||
showPerDialog.value = true
|
||||
value = val
|
||||
await nextTick()
|
||||
personnel.value.open()
|
||||
}
|
||||
const submituser = (e) => {
|
||||
formData[value] = e.name
|
||||
formData[value + "_id"] = e.id
|
||||
showPerDialog.value = false
|
||||
}
|
||||
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
</script>
|
11
src/views/oa_Initiate/form/rs/rza.js
Normal file
11
src/views/oa_Initiate/form/rs/rza.js
Normal file
@ -0,0 +1,11 @@
|
||||
const rza = {
|
||||
jyr: "员工姓名",
|
||||
lwrq: "入职时间",
|
||||
wjmc: "手机号码",
|
||||
sex: "性别",
|
||||
rzbm: "入职部门",
|
||||
drzw: "担任职务",
|
||||
bz1: "备注",
|
||||
|
||||
}
|
||||
export default rza
|
156
src/views/oa_Initiate/form/rs/zg.vue
Normal file
156
src/views/oa_Initiate/form/rs/zg.vue
Normal file
@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="员工姓名" prop="jyr">
|
||||
<el-input v-model="formData.jyr" clearable placeholder="请输入员工姓名" @click="userclick('jyr')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="入职时间" prop="lwrq">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.lwrq" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择入职时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="当前所在部门" prop="rzbm">
|
||||
<el-select v-model="formData.rzbm" placeholder="请选择当前所在部门" class="flex-1">
|
||||
<el-option :label="item.name" :value="item.name" v-for="item in deptList">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="担任职务" prop="drzw">
|
||||
<el-select v-model="formData.drzw" placeholder="请选择担任职务" class="flex-1">
|
||||
<el-option :label="item.name" :value="item.name" v-for="item in zwlist">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="转岗后所在部门" prop="rzbm">
|
||||
<el-select v-model="formData.rzbm1" placeholder="请选择转岗后所在部门" class="flex-1">
|
||||
<el-option :label="item.name" :value="item.name" v-for="item in deptList">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="转刚后职务" prop="drzw">
|
||||
<el-select v-model="formData.drzw1" placeholder="请选择转刚后职务" class="flex-1">
|
||||
<el-option :label="item.name" :value="item.name" v-for="item in zwlist">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item label="申请转岗日期" prop="lwrq1">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.lwrq1" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择申请转岗日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="预计转刚日期" prop="lwrq2">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.lwrq2" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择预计转刚日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="转岗原因" prop="bz1">
|
||||
<el-input v-model="formData.bz1" clearable placeholder="请输入转岗原因" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="附件">
|
||||
<uploadAnnex :form-data="formData"></uploadAnnex>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div v-if="showPerDialog">
|
||||
<personnelselector ref="personnel" @confirm="submituser" type="1">
|
||||
</personnelselector>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { deptLists } from "@/api/org/department";
|
||||
import { jobsLists } from '@/api/org/post'
|
||||
|
||||
let list = ['jyr', 'lwrq', 'wjmc', 'sex', 'rzbm', "drzw", 'lwrq1', 'lwrq2', 'bz1', 'rzbm1', 'drzw1']
|
||||
|
||||
const qjlxList = reactive(['差旅费', '办公费', '招待费', '交通费', '通讯费', '采购付款', '其他'])
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
})
|
||||
const formRef = ref(null)
|
||||
|
||||
|
||||
|
||||
const deptList = ref([])
|
||||
const getDeptList = async () => {
|
||||
const res = await deptLists()
|
||||
deptList.value = res.lists
|
||||
}
|
||||
getDeptList()
|
||||
|
||||
|
||||
const zwlist = ref([])
|
||||
const getzwlist = async () => {
|
||||
const res = await jobsLists()
|
||||
zwlist.value = res.lists
|
||||
}
|
||||
getzwlist()
|
||||
|
||||
|
||||
|
||||
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
})
|
||||
|
||||
const setRules = () => {
|
||||
list.forEach(item => {
|
||||
formRules[item] = [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
setRules()
|
||||
|
||||
|
||||
|
||||
const showPerDialog = ref(false)
|
||||
const personnel = ref(null)
|
||||
|
||||
let value
|
||||
const userclick = async (val) => {
|
||||
showPerDialog.value = true
|
||||
value = val
|
||||
await nextTick()
|
||||
personnel.value.open()
|
||||
}
|
||||
const submituser = (e) => {
|
||||
props.formData[value] = e.name
|
||||
props.formData[value + "_id"] = e.id
|
||||
showPerDialog.value = false
|
||||
}
|
||||
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
</script>
|
13
src/views/oa_Initiate/form/rs/zga.js
Normal file
13
src/views/oa_Initiate/form/rs/zga.js
Normal file
@ -0,0 +1,13 @@
|
||||
const zga = {
|
||||
jyr: "员工姓名",
|
||||
lwrq: "入职时间",
|
||||
rzbm: "当前所在部门",
|
||||
drzw: "担任职务",
|
||||
rzbm1: "转岗后所在部门",
|
||||
drzw1: "转刚后职务",
|
||||
lwrq1: "申请转岗日期",
|
||||
lwrq2: "预计转刚日期",
|
||||
bz1: "转岗原因",
|
||||
|
||||
}
|
||||
export default zga
|
113
src/views/oa_Initiate/form/rs/zpxq.vue
Normal file
113
src/views/oa_Initiate/form/rs/zpxq.vue
Normal file
@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="招聘部门" prop="rzbm">
|
||||
<el-select v-model="formData.rzbm" placeholder="请选择招聘部门" class="flex-1">
|
||||
<el-option :label="item.name" :value="item.name" v-for="item in deptList">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="期望到岗日期" prop="lwrq1">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.lwrq1" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择期望到岗日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="招聘岗位" prop="drzw">
|
||||
<el-select v-model="formData.drzw" placeholder="请选择招聘岗位" class="flex-1">
|
||||
<el-option :label="item.name" :value="item.name" v-for="item in zwlist">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="招聘人数" prop="bz1">
|
||||
<el-input v-model="formData.bz1" clearable placeholder="请输入招聘人数" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item label="岗位职责" prop="gwzz">
|
||||
<el-input v-model="formData.gwzz" clearable placeholder="请输入岗位职责" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item label="任职要求" prop="rzyq">
|
||||
<el-input v-model="formData.rzyq" clearable placeholder="请输入任职要求" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="附件">
|
||||
<uploadAnnex :form-data="formData"></uploadAnnex>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { deptLists } from "@/api/org/department";
|
||||
import { jobsLists } from '@/api/org/post'
|
||||
|
||||
let list = ['jyr', 'lwrq', 'wjmc', 'sex', 'rzbm', "drzw", 'lwrq1', 'lwrq2', 'bz1', 'gwzz', 'rzyq']
|
||||
|
||||
const qjlxList = reactive(['差旅费', '办公费', '招待费', '交通费', '通讯费', '采购付款', '其他'])
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
})
|
||||
const formRef = ref(null)
|
||||
|
||||
|
||||
|
||||
const deptList = ref([])
|
||||
const getDeptList = async () => {
|
||||
const res = await deptLists()
|
||||
deptList.value = res.lists
|
||||
}
|
||||
getDeptList()
|
||||
|
||||
|
||||
const zwlist = ref([])
|
||||
const getzwlist = async () => {
|
||||
const res = await jobsLists()
|
||||
zwlist.value = res.lists
|
||||
}
|
||||
getzwlist()
|
||||
|
||||
|
||||
|
||||
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
})
|
||||
|
||||
const setRules = () => {
|
||||
list.forEach(item => {
|
||||
formRules[item] = [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
setRules()
|
||||
|
||||
|
||||
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
</script>
|
10
src/views/oa_Initiate/form/rs/zpxqa.js
Normal file
10
src/views/oa_Initiate/form/rs/zpxqa.js
Normal file
@ -0,0 +1,10 @@
|
||||
const zpxqa = {
|
||||
rzbm: "招聘部门",
|
||||
lwrq1: "期望到岗日期",
|
||||
drzw: "招聘岗位",
|
||||
bz1: "招聘人数",
|
||||
gwzz: "岗位职责",
|
||||
rzyq: "任职要求",
|
||||
|
||||
}
|
||||
export default zpxqa
|
124
src/views/oa_Initiate/form/rs/zz.vue
Normal file
124
src/views/oa_Initiate/form/rs/zz.vue
Normal file
@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="员工姓名" prop="jyr">
|
||||
<el-input v-model="formData.jyr" clearable placeholder="请输入员工姓名" @click="userclick('jyr')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="转正日期" prop="lwrq">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.lwrq" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择转正日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="所在部门" prop="rzbm">
|
||||
<el-select v-model="formData.rzbm" placeholder="请选择入职部门" class="flex-1">
|
||||
<el-option :label="item.name" :value="item.name" v-for="item in deptList">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="担任职务" prop="drzw">
|
||||
<el-select v-model="formData.drzw" placeholder="请选择担任职务" class="flex-1">
|
||||
<el-option :label="item.name" :value="item.name" v-for="item in zwlist">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="试用期评价" prop="bz1">
|
||||
<el-input v-model="formData.bz1" clearable placeholder="请输入试用期评价" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="附件">
|
||||
<uploadAnnex :form-data="formData"></uploadAnnex>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div v-if="showPerDialog">
|
||||
<personnelselector ref="personnel" @confirm="submituser" type="1">
|
||||
</personnelselector>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { deptLists } from "@/api/org/department";
|
||||
import { jobsLists } from '@/api/org/post'
|
||||
|
||||
let list = ['jyr', 'lwrq', 'wjmc', 'sex', 'rzbm', "drzw", 'bz1']
|
||||
|
||||
const qjlxList = reactive(['差旅费', '办公费', '招待费', '交通费', '通讯费', '采购付款', '其他'])
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
})
|
||||
const formRef = ref(null)
|
||||
|
||||
|
||||
|
||||
const deptList = ref([])
|
||||
const getDeptList = async () => {
|
||||
const res = await deptLists()
|
||||
deptList.value = res.lists
|
||||
}
|
||||
getDeptList()
|
||||
|
||||
|
||||
const zwlist = ref([])
|
||||
const getzwlist = async () => {
|
||||
const res = await jobsLists()
|
||||
zwlist.value = res.lists
|
||||
}
|
||||
getzwlist()
|
||||
|
||||
|
||||
|
||||
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
})
|
||||
|
||||
const setRules = () => {
|
||||
list.forEach(item => {
|
||||
formRules[item] = [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
setRules()
|
||||
|
||||
|
||||
|
||||
const showPerDialog = ref(false)
|
||||
const personnel = ref(null)
|
||||
|
||||
let value
|
||||
const userclick = async (val) => {
|
||||
showPerDialog.value = true
|
||||
value = val
|
||||
await nextTick()
|
||||
personnel.value.open()
|
||||
}
|
||||
const submituser = (e) => {
|
||||
props.formData[value] = e.name
|
||||
props.formData[value + "_id"] = e.id
|
||||
showPerDialog.value = false
|
||||
}
|
||||
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
</script>
|
8
src/views/oa_Initiate/form/rs/zza.js
Normal file
8
src/views/oa_Initiate/form/rs/zza.js
Normal file
@ -0,0 +1,8 @@
|
||||
const zza = {
|
||||
jyr: "员工姓名",
|
||||
lwrq: "转正日期",
|
||||
rzbm: "所在部门",
|
||||
drzw: "担任职务",
|
||||
bz1: "试用期评价",
|
||||
}
|
||||
export default zza
|
104
src/views/oa_Initiate/form/xz/gwlz.vue
Normal file
104
src/views/oa_Initiate/form/xz/gwlz.vue
Normal file
@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="文件名称" prop="wjmc">
|
||||
<el-input v-model="formData.wjmc" clearable placeholder="请输入文件名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="紧急程度" prop="jjcd">
|
||||
<el-select v-model="formData.jjcd" placeholder="请选择紧急程度" class="flex-1">
|
||||
<el-option :label="item" :value="item" v-for="(item, index) in qjlxList" :key="index">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="来文单位" prop="lwdw">
|
||||
<el-input v-model="formData.lwdw" clearable placeholder="请输入来文单位" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="来文日期" prop="lwrq">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.lwrq" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择来文日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="文件摘要" prop="wjzy">
|
||||
<el-input v-model="formData.wjzy" clearable placeholder="请输入文件摘要" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="formData.bz" clearable placeholder="请输入备注" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const qjlxList = reactive(['普通', '紧急', '特急'])
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
})
|
||||
const formRef = ref(null)
|
||||
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
wjmc: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
lwdw: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
lwrq: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
wjzy: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
kssj: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
jssj: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
jjcd: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
lwdw: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
|
||||
})
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
|
||||
</script>
|
9
src/views/oa_Initiate/form/xz/gwlza.js
Normal file
9
src/views/oa_Initiate/form/xz/gwlza.js
Normal file
@ -0,0 +1,9 @@
|
||||
const gwlza = {
|
||||
wjmc: "文件名称",
|
||||
jjcd: "紧急程度",
|
||||
lwdw: "来文单位",
|
||||
lwrq: "来文日期",
|
||||
wjzy: "文件摘要",
|
||||
bz: "备注",
|
||||
}
|
||||
export default gwlza
|
99
src/views/oa_Initiate/form/xz/hysyd.vue
Normal file
99
src/views/oa_Initiate/form/xz/hysyd.vue
Normal file
@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="会议室选择" prop="hysxz">
|
||||
<el-select v-model="formData.hysxz" placeholder="请选择会议室" class="flex-1">
|
||||
<el-option :label="item" :value="item" v-for="(item, index) in qjlxList" :key="index">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="开始时间" prop="kssj">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.kssj" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="结束时间" prop="jssj">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.jssj" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择结束时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="formData.bz" clearable placeholder="请输入备注" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="附件">
|
||||
<uploadAnnex :form-data="formData"></uploadAnnex>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const qjlxList = reactive(['会议室一', '会议室二', '会议室三'])
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
})
|
||||
const formRef = ref(null)
|
||||
|
||||
|
||||
const checkDate = (rule: any, value: any, callback: any) => {
|
||||
if (new Date(props.formData.jssj) < new Date(props.formData.kssj)) {
|
||||
callback(new Error('结束时间不能早于开始时间'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
hysxz: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
kssj: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
jssj: [
|
||||
{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
},
|
||||
{
|
||||
validator: checkDate,
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
jbsy: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
})
|
||||
|
||||
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
|
||||
</script>
|
7
src/views/oa_Initiate/form/xz/hysyda.js
Normal file
7
src/views/oa_Initiate/form/xz/hysyda.js
Normal file
@ -0,0 +1,7 @@
|
||||
const hysyda = {
|
||||
item: "会议室选择",
|
||||
kssj: "开始时间",
|
||||
jssj: "结束时间",
|
||||
bz: "备注",
|
||||
}
|
||||
export default hysyda
|
124
src/views/oa_Initiate/form/xz/wpwx.vue
Normal file
124
src/views/oa_Initiate/form/xz/wpwx.vue
Normal file
@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="故障设备名称" prop="gzsbmc">
|
||||
<el-input v-model="formData.gzsbmc" clearable placeholder="请输入故障设备名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="紧急程度" prop="jjcd">
|
||||
<el-select v-model="formData.jjcd" placeholder="请选择紧急程度" class="flex-1">
|
||||
<el-option :label="item" :value="item" v-for="(item, index) in qjlxList" :key="index">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="预计维修费用" prop="yjwxfy">
|
||||
<el-input v-model="formData.yjwxfy" clearable placeholder="请输入预计维修费用" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="报修日期" prop="bxrq">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.bxrq" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择报修日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="故障描述" prop="gzms">
|
||||
<el-input v-model="formData.gzms" clearable placeholder="请输入故障描述" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="附件">
|
||||
<uploadAnnex :form-data="formData"></uploadAnnex>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const qjlxList = reactive(['普通', '紧急', '特急'])
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
})
|
||||
const formRef = ref(null)
|
||||
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
gzsbmc: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
yjwxfy: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
bxrq: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
gzms: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
jjcd: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
lwrq: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
wjzy: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
|
||||
|
||||
kssj: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
jssj: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
jbsy: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
})
|
||||
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
|
||||
</script>
|
8
src/views/oa_Initiate/form/xz/wpwxa.js
Normal file
8
src/views/oa_Initiate/form/xz/wpwxa.js
Normal file
@ -0,0 +1,8 @@
|
||||
const wpwxa = {
|
||||
gzsbmc: "故障设备名称",
|
||||
jjcd: "紧急程度",
|
||||
yjwxfy: "预计维修费用",
|
||||
bxrq: "报修日期",
|
||||
gzms: "故障描述",
|
||||
}
|
||||
export default wpwxa
|
129
src/views/oa_Initiate/form/xz/yc.vue
Normal file
129
src/views/oa_Initiate/form/xz/yc.vue
Normal file
@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="formData" label-width="110px" :rules="formRules">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="开始时间" prop="kssj">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.kssj" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间" @change="calcDay">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="结束时间" prop="jssj">
|
||||
<el-date-picker class="flex-1 !flex" v-model="formData.jssj" clearable type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择结束时间" @change="calcDay">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="用车天数">
|
||||
<el-input v-model="formData.qjts" clearable placeholder="系统自动计算" readonly />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="用车目的地" prop="mdd">
|
||||
<el-input v-model="formData.mdd" clearable placeholder="请输入用车目的地" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="车辆选择" prop="clxz">
|
||||
<el-select v-model="formData.clxz" placeholder="请选择车辆选择" class="flex-1">
|
||||
<el-option :label="item.name" :value="item.name" v-for="(item, index) in carLists" :key="index">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item label="用车事由" prop="ccsy">
|
||||
<el-input v-model="formData.ccsy" clearable placeholder="请输入用车事由" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const qjlxList = reactive(['事假', '年假', '调休假', '病假', '婚假', '产假', '陪产假', '其他'])
|
||||
let props = defineProps({
|
||||
formData: Object,
|
||||
})
|
||||
const formRef = ref(null)
|
||||
import { apiOaCarCateLists } from '@/api/oa_car_cate'
|
||||
let carLists = ref([])
|
||||
apiOaCarCateLists().then(res => {
|
||||
carLists.value = res.lists
|
||||
})
|
||||
|
||||
|
||||
const calcDay = () => {
|
||||
const date1 = props.formData.kssj;
|
||||
const date2 = props.formData?.jssj;
|
||||
if (date1 && date2) {
|
||||
const timeDiff = new Date(date2).getTime() - new Date(date1).getTime();
|
||||
const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24));
|
||||
props.formData.qjts = daysDiff || 0
|
||||
}
|
||||
}
|
||||
|
||||
const checkDate = (rule: any, value: any, callback: any) => {
|
||||
if (new Date(props.formData.jssj) < new Date(props.formData.kssj)) {
|
||||
callback(new Error('结束时间不能早于开始时间'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
// 表单验证
|
||||
const formRules = reactive({
|
||||
qjlx: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
kssj: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
jssj: [
|
||||
{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
},
|
||||
{
|
||||
validator: checkDate,
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
ccsy: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
mdd: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
clxz: [{
|
||||
required: true,
|
||||
message: '不可为空',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
|
||||
|
||||
})
|
||||
|
||||
const check = async () => {
|
||||
await formRef.value?.validate();
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
check
|
||||
});
|
||||
|
||||
</script>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user