Initial commit
This commit is contained in:
476
src/views/oa/order/components/order-edit.vue
Normal file
476
src/views/oa/order/components/order-edit.vue
Normal file
@@ -0,0 +1,476 @@
|
||||
<!-- 编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
width="70%"
|
||||
:visible="visible"
|
||||
:maskClosable="false"
|
||||
:maxable="maxable"
|
||||
:title="isUpdate ? '编辑订单' : '新增订单'"
|
||||
:body-style="{ paddingBottom: '28px' }"
|
||||
@update:visible="updateVisible"
|
||||
@ok="save"
|
||||
>
|
||||
<div style="background-color: #f3f3f3; padding: 8px">
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
:label-col="{ md: { span: 7 }, sm: { span: 4 }, xs: { span: 24 } }"
|
||||
:wrapper-col="{ md: { span: 17 }, sm: { span: 20 }, xs: { span: 24 } }"
|
||||
>
|
||||
<a-card title="基本信息" :bordered="false">
|
||||
<!-- <template #extra>-->
|
||||
<!-- <a-button type="link" @click="handleEditStatus">{{ editStatus ? "预览" : "编辑" }}</a-button>-->
|
||||
<!-- </template>-->
|
||||
<a-row :gutter="16">
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 12, sm: 24, xs: 24 } : { span: 8 }"
|
||||
>
|
||||
<a-form-item label="订单金额" name="money">
|
||||
<a-input
|
||||
allow-clear
|
||||
:maxlength="20"
|
||||
placeholder="请输入订单金额"
|
||||
v-if="editStatus"
|
||||
v-model:value="form.money"
|
||||
/>
|
||||
<span v-else class="ele-text-primary">{{ form.money }}</span>
|
||||
</a-form-item>
|
||||
<a-form-item label="选择用户" name="userId">
|
||||
<SelectUser
|
||||
:placeholder="`选择用户`"
|
||||
v-model:value="form.userId"
|
||||
v-if="editStatus"
|
||||
@done="chooseUserId"
|
||||
/>
|
||||
<span v-else class="ele-text-primary">{{ form.nickname }}</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col
|
||||
v-bind="styleResponsive ? { md: 12, sm: 24, xs: 24 } : { span: 8 }"
|
||||
>
|
||||
<a-form-item label="实际付款金额" name="payPrice">
|
||||
<a-input
|
||||
allow-clear
|
||||
:maxlength="20"
|
||||
placeholder="请输入订单金额"
|
||||
v-if="editStatus"
|
||||
v-model:value="form.payPrice"
|
||||
/>
|
||||
<span v-else class="ele-text-primary">{{ form.payPrice }}</span>
|
||||
</a-form-item>
|
||||
<a-form-item label="备注信息" name="comments">
|
||||
<a-textarea
|
||||
:rows="4"
|
||||
:maxlength="200"
|
||||
placeholder="备注信息"
|
||||
v-if="editStatus"
|
||||
v-model:value="form.comments"
|
||||
/>
|
||||
<span v-else class="ele-text-primary">{{ form.comments }}</span>
|
||||
</a-form-item>
|
||||
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</a-form>
|
||||
</div>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch, createVNode, computed } from "vue";
|
||||
import { Form, message } from "ant-design-vue";
|
||||
import { assignObject, ipReg, toDateString } from "ele-admin-pro";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { useThemeStore } from "@/store/modules/theme";
|
||||
import { storeToRefs } from "pinia";
|
||||
// 中文语言文件
|
||||
import zh_Hans from "bytemd/locales/zh_Hans.json";
|
||||
// 链接、删除线、复选框、表格等的插件
|
||||
// 插件的中文语言文件
|
||||
import zh_HansGfm from "@bytemd/plugin-gfm/locales/zh_Hans.json";
|
||||
import "bytemd/dist/index.min.css";
|
||||
import "github-markdown-css/github-markdown-light.css";
|
||||
import { Modal } from "ant-design-vue";
|
||||
// import TinymceEditor from '@/components/TinymceEditor/index.vue';
|
||||
import highlight from "@bytemd/plugin-highlight";
|
||||
// 中文语言文件
|
||||
import gfm from "@bytemd/plugin-gfm";
|
||||
// // 预览界面的样式,这里用的 github 的 markdown 主题
|
||||
import "github-markdown-css/github-markdown-light.css";
|
||||
import {
|
||||
EyeOutlined,
|
||||
EyeInvisibleOutlined,
|
||||
EnvironmentOutlined
|
||||
} from "@ant-design/icons-vue";
|
||||
import { UploadOutlined } from "@/layout/menu-icons";
|
||||
import { FormInstance, RuleObject } from "ant-design-vue/es/form";
|
||||
import { Order } from "@/api/oa/order/model";
|
||||
import { ItemType } from "ele-admin-pro/es/ele-image-upload/types";
|
||||
import { User } from "@/api/system/user/model";
|
||||
import { uploadFile } from "@/api/system/file";
|
||||
import { FILE_SERVER, FILE_THUMBNAIL, TOKEN_STORE_NAME } from "@/config/setting";
|
||||
import { listOrder, addOrder, updateOrder, removeOrder } from "@/api/oa/order";
|
||||
import { isIP } from "ele-admin-pro";
|
||||
import { Dayjs } from "dayjs";
|
||||
import { Company } from '@/api/system/company/model';
|
||||
|
||||
// 是否是修改
|
||||
const isUpdate = ref(false);
|
||||
const useForm = Form.useForm;
|
||||
// 是否开启响应式布局
|
||||
const themeStore = useThemeStore();
|
||||
const { styleResponsive } = storeToRefs(themeStore);
|
||||
const { darkMode } = storeToRefs(themeStore);
|
||||
const props = defineProps<{
|
||||
// 弹窗是否打开
|
||||
visible: boolean;
|
||||
// 修改回显的数据
|
||||
data?: Order | null;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "done"): void;
|
||||
(e: "update:visible", visible: boolean): void;
|
||||
}>();
|
||||
|
||||
// 提交状态
|
||||
const loading = ref(false);
|
||||
// 是否显示最大化切换按钮
|
||||
const maxable = ref(true);
|
||||
// 当期时间
|
||||
const dayTime = toDateString(new Date());
|
||||
// 已上传数据
|
||||
const images = ref<ItemType[]>([]);
|
||||
const orderUsers = ref<Order[]>([]);
|
||||
const selectUser = ref<string>();
|
||||
const editStatus = ref(true);
|
||||
const formRef = ref<FormInstance | null>(null);
|
||||
// const type = ref<string>('single');
|
||||
// 日期范围选择
|
||||
const dateRange = ref<[string, string]>(["", ""]);
|
||||
const content = ref("");
|
||||
const requirement = ref("");
|
||||
// 插件
|
||||
const plugins = ref([
|
||||
gfm({
|
||||
locale: zh_HansGfm
|
||||
}),
|
||||
highlight()
|
||||
]);
|
||||
|
||||
// 购买日期
|
||||
const startTime = ref<Dayjs>();
|
||||
// 结束日期
|
||||
const endTime = ref<Dayjs>();
|
||||
const showAddUserForm = ref(false);
|
||||
|
||||
// 文件模型
|
||||
interface FileItem {
|
||||
uid: string;
|
||||
name?: string;
|
||||
status?: string;
|
||||
response?: Response;
|
||||
thumbUrl?: string;
|
||||
downloadUrl?: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
interface FileInfo {
|
||||
file: FileItem;
|
||||
fileList: FileItem[];
|
||||
}
|
||||
|
||||
// 文件上传
|
||||
const file1 = ref<FileItem[]>();
|
||||
const file2 = ref<FileItem[]>();
|
||||
const file3 = ref<FileItem[]>();
|
||||
|
||||
// 用户信息
|
||||
const form = reactive<Order>({
|
||||
orderId: undefined,
|
||||
orderNo: '',
|
||||
type: undefined,
|
||||
logo: '',
|
||||
money: undefined,
|
||||
payPrice: undefined,
|
||||
planId: undefined,
|
||||
priceId: undefined,
|
||||
gradeId: undefined,
|
||||
userId: '',
|
||||
companyId: undefined,
|
||||
nickname: '',
|
||||
username: '',
|
||||
userAvatar: '',
|
||||
shopId: '',
|
||||
sortNumber: undefined,
|
||||
comments: '',
|
||||
status: undefined,
|
||||
createTime: '',
|
||||
updateTime: '',
|
||||
company: undefined
|
||||
});
|
||||
|
||||
/* 更新visible */
|
||||
const updateVisible = (value: boolean) => {
|
||||
emit("update:visible", value);
|
||||
};
|
||||
|
||||
// 表单验证规则
|
||||
const rules = reactive({
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
type: "string",
|
||||
message: "请输入订单名称",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
code: [
|
||||
{
|
||||
required: true,
|
||||
type: "string",
|
||||
message: "请输入合法的IP地址",
|
||||
trigger: "blur",
|
||||
validator: async (_rule: RuleObject, value: string) => {
|
||||
if (!isIP(value)) {
|
||||
const msg = "请输入合法的IP地址";
|
||||
try {
|
||||
if (!isIP(value)) {
|
||||
return Promise.reject(msg);
|
||||
}
|
||||
} catch (_e) {
|
||||
return Promise.reject(msg);
|
||||
}
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
],
|
||||
brand: [
|
||||
{
|
||||
required: true,
|
||||
type: "string",
|
||||
message: "请选择跟进状态",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
companyName: [
|
||||
{
|
||||
required: true,
|
||||
type: "string",
|
||||
message: "请选择所属企业",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
// orderName: [
|
||||
// {
|
||||
// required: true,
|
||||
// type: 'string',
|
||||
// message: '请选择租赁单位',
|
||||
// trigger: 'blur'
|
||||
// }
|
||||
// ],
|
||||
// appRegion: [
|
||||
// {
|
||||
// required: true,
|
||||
// type: 'string',
|
||||
// message: '请输入订单地址',
|
||||
// trigger: 'blur'
|
||||
// }
|
||||
// ]
|
||||
});
|
||||
|
||||
const { resetFields, validate, validateInfos } = useForm(form, rules);
|
||||
|
||||
const addUser = () => {
|
||||
showAddUserForm.value = true;
|
||||
};
|
||||
|
||||
// 所属用户
|
||||
const chooseUserId = (data: User) => {
|
||||
form.userId = data.userId;
|
||||
form.nickname = data.nickname;
|
||||
};
|
||||
|
||||
const handleEditStatus = () => {
|
||||
editStatus.value = !editStatus.value;
|
||||
};
|
||||
|
||||
// const chooseOrderName = (data: Order) => {
|
||||
// form.orderName = data.orderName;
|
||||
// };
|
||||
|
||||
const onFile1 = (info: FileInfo) => {
|
||||
let resFileList = [...info.fileList];
|
||||
file1.value = resFileList.map((file) => {
|
||||
if (file.response) {
|
||||
file.url = file.response.url;
|
||||
}
|
||||
return file;
|
||||
});
|
||||
};
|
||||
|
||||
const config = ref({
|
||||
width: 1000,
|
||||
height: 500,
|
||||
images_upload_handler: (blobInfo, success, error) => {
|
||||
const file = blobInfo.blob();
|
||||
// 使用 axios 上传,实际开发这段建议写在 api 中再调用 api
|
||||
const formData = new FormData();
|
||||
formData.append("file", file, file.name);
|
||||
uploadFile(<File>file)
|
||||
.then((result) => {
|
||||
if (result.length) {
|
||||
if (file.size / 1024 / 1024 > 2) {
|
||||
error("图片大小不能超过 2MB");
|
||||
}
|
||||
success(FILE_SERVER + result.path);
|
||||
} else {
|
||||
error("上传失败");
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
message.error(e.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 上传文件
|
||||
const onUpload = (item) => {
|
||||
const { file } = item;
|
||||
images.value = [];
|
||||
uploadFile(file)
|
||||
.then((data) => {
|
||||
images.value.push({
|
||||
uid: data.id,
|
||||
url: FILE_THUMBNAIL + data.path,
|
||||
status: "done"
|
||||
});
|
||||
message.success("上传成功");
|
||||
})
|
||||
.catch((e) => {
|
||||
message.error(e.message);
|
||||
});
|
||||
};
|
||||
|
||||
/* 粘贴图片上传订单并插入编辑器 */
|
||||
const onPaste = (e) => {
|
||||
console.log(e);
|
||||
const items = (e.clipboardData || e.originalEvent.clipboardData).items;
|
||||
console.log(items);
|
||||
let hasFile = false;
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].type.indexOf("image") !== -1) {
|
||||
let file = items[i].getAsFile();
|
||||
const item: ItemType = {
|
||||
file,
|
||||
uid: (file as any).lastModified,
|
||||
name: file.name
|
||||
};
|
||||
uploadFile(<File>item.file)
|
||||
.then((result) => {
|
||||
const addPath = "\n\r";
|
||||
content.value = content.value + addPath;
|
||||
})
|
||||
.catch((e) => {
|
||||
message.error(e.message);
|
||||
});
|
||||
hasFile = true;
|
||||
}
|
||||
}
|
||||
if (hasFile) {
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
/* 保存编辑 */
|
||||
const save = () => {
|
||||
if (!formRef.value) {
|
||||
return;
|
||||
}
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
loading.value = true;
|
||||
const formData = {
|
||||
...form,
|
||||
content: content.value
|
||||
};
|
||||
// 转字符串
|
||||
const saveOrUpdate = isUpdate.value ? updateOrder : addOrder;
|
||||
saveOrUpdate(formData)
|
||||
.then((msg) => {
|
||||
loading.value = false;
|
||||
message.success(msg);
|
||||
updateVisible(false);
|
||||
emit("done");
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.value = false;
|
||||
message.error(e.message);
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
};
|
||||
|
||||
const reload = () => {
|
||||
loading.value = true;
|
||||
// 加载项目成员
|
||||
listOrder({orderId:props.data?.orderId}).then(data => {
|
||||
orderUsers.value = data
|
||||
})
|
||||
// 加载企业信息
|
||||
const companyId = props.data?.companyId;
|
||||
// pageCompany({companyId}).then(res => {
|
||||
// form.tenantId = undefined;
|
||||
// const list = res?.list;
|
||||
// if(list && list.length > 0){
|
||||
// form.tenantId = list[0].tenantId;
|
||||
// }
|
||||
// })
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
content.value = "";
|
||||
requirement.value = "";
|
||||
if (props.data) {
|
||||
assignObject(form, props.data);
|
||||
images.value = [];
|
||||
isUpdate.value = true;
|
||||
reload();
|
||||
} else {
|
||||
isUpdate.value = false;
|
||||
editStatus.value = true;
|
||||
}
|
||||
} else {
|
||||
resetFields();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.tab-pane {
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.ml-10 {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.upload-text {
|
||||
margin-right: 70px;
|
||||
}
|
||||
|
||||
.upload-image {
|
||||
margin-bottom: 30px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
101
src/views/oa/order/components/search.vue
Normal file
101
src/views/oa/order/components/search.vue
Normal file
@@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<div style="display: flex; justify-content: space-between">
|
||||
<a-space style="flex-wrap: wrap">
|
||||
<a-button type="primary" class="ele-btn-icon" @click="add">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
<span>新增</span>
|
||||
</a-button>
|
||||
<a-radio-group v-model:value="where.status" @change="search">
|
||||
<a-radio-button>订单类型</a-radio-button>
|
||||
<a-radio-button value="0">待处理</a-radio-button>
|
||||
<a-radio-button value="1">已完成</a-radio-button>
|
||||
</a-radio-group>
|
||||
订单状态:
|
||||
<a-radio-group v-model:value="where.status" @change="search">
|
||||
<a-radio-button value="0">待支付</a-radio-button>
|
||||
<a-radio-button value="1">待发货</a-radio-button>
|
||||
<a-radio-button value="2">待收货</a-radio-button>
|
||||
<a-radio-button value="3">已完成</a-radio-button>
|
||||
</a-radio-group>
|
||||
<a-button
|
||||
danger
|
||||
v-if="selection?.length"
|
||||
class="ele-btn-icon"
|
||||
@click="removeBatch"
|
||||
>
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
<span>批量删除</span>
|
||||
</a-button>
|
||||
</a-space>
|
||||
<a-space :size="10" style="flex-wrap: wrap; margin-right: 20px">
|
||||
<DictSelect
|
||||
dict-code="productType"
|
||||
v-model:value="where.categoryId"
|
||||
:placeholder="`选择分类`"
|
||||
style="width: 200px"
|
||||
@change="search"
|
||||
/>
|
||||
<a-input-search
|
||||
allow-clear
|
||||
placeholder="产品名称"
|
||||
v-model:value="where.keywords"
|
||||
@pressEnter="search"
|
||||
@search="search"
|
||||
/>
|
||||
<a-button @click="reset">重置</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ProductParam } from '@/api/oa/product/model';
|
||||
import useSearch from '@/utils/use-search';
|
||||
import {DeleteOutlined, PlusOutlined} from '@ant-design/icons-vue';
|
||||
import DictSelect from '@/components/DictSelect/index.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
// 勾选的项目
|
||||
selection?: [];
|
||||
status?: number;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'search', where: ProductParam): void;
|
||||
(e: 'add'): void;
|
||||
(e: 'remove'): void;
|
||||
}>();
|
||||
|
||||
// 表单数据
|
||||
const { where, resetFields } = useSearch<ProductParam>({
|
||||
keywords: '',
|
||||
status: undefined
|
||||
});
|
||||
|
||||
const removeBatch = () => {
|
||||
emit('remove');
|
||||
};
|
||||
|
||||
// 发布应用
|
||||
const add = () => {
|
||||
emit('add');
|
||||
};
|
||||
|
||||
/* 重置 */
|
||||
const reset = () => {
|
||||
resetFields();
|
||||
search();
|
||||
};
|
||||
|
||||
/* 搜索 */
|
||||
const search = () => {
|
||||
emit('search', where);
|
||||
};
|
||||
|
||||
if (props.status == undefined) {
|
||||
where.status = '1';
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user