Commit 44bafec7ae189e8245d66e8d50c619d92b783f96

Authored by 杨泽宇
1 parent 0851365b

活动报名增加字段 多图上传组件

docs/develop/component.md
@@ -30,6 +30,20 @@ @@ -30,6 +30,20 @@
30 | url | `String` | required | 上传地址 | | 30 | url | `String` | required | 上传地址 | |
31 | method | `String` | required | 请求方式 | | 31 | method | `String` | required | 请求方式 | |
32 32
  33 +## 多图上传
  34 + * 代码位置:[src/components/Photowall](http://bj.gitlab.cnlive.com/cnlive_project/cnlive-community-web-vue/blob/dev/src/components/Photowall)
  35 + * Emit: `finish(images[], tagName)`
  36 + * 组件属性:
  37 +
  38 + | propName | propType | propAttr | propDesc | propDefault |
  39 + | :-----: | :-----: | :-----: | :--: | :--: |
  40 + | tagName | `String` | optional | 标签 | |
  41 + | maxSize | `Number` | optional | 图片尺寸上限 | 1MB |
  42 + | fileList | `Array` | optional | 默认图片 | |
  43 + | moduleName | `String` | optional | 后台交互用的module值 | test |
  44 + | tip | `String` | optional | 上传须知 | 最多可以上传9张图片,单张图片大小不可超过1MB |
  45 + | formats | `Array<String>` | optional | 图片格式 | [图片格式](develop/component?id=图片格式) |
  46 +
33 ## 单图上传 47 ## 单图上传
34 * 代码位置:[src/components/Uploader](http://bj.gitlab.cnlive.com/cnlive_project/cnlive-community-web-vue/blob/dev/src/components/Uploader) 48 * 代码位置:[src/components/Uploader](http://bj.gitlab.cnlive.com/cnlive_project/cnlive-community-web-vue/blob/dev/src/components/Uploader)
35 * Emit: `imageChange(url, tagName)` 49 * Emit: `imageChange(url, tagName)`
docs/develop/discuss.md
@@ -34,7 +34,21 @@ @@ -34,7 +34,21 @@
34 > * 当前登录的用户是物业管理员,表单里才有关联小区。 34 > * 当前登录的用户是物业管理员,表单里才有关联小区。
35 > * 查看登录成功返回值[释义](http://bj.gitlab.cnlive.com/cnlive_project/cnlive-community-web-vue/blob/dev/src/pinia/login.ts "释义") 35 > * 查看登录成功返回值[释义](http://bj.gitlab.cnlive.com/cnlive_project/cnlive-community-web-vue/blob/dev/src/pinia/login.ts "释义")
36 36
  37 +## 小区管理
  38 + **关联小区**
  39 + > * 【活动】关联小区,调【机构下小区】接口。
  40 + > * 【机构】关联小区,调【全部小区】接口。
  41 + > * 【工单列表】小区回显,调【全部小区】接口。
  42 + > * 【工单】关联小区,调【小区】接口。
  43 + > * 【通知】关联小区,调【小区】接口。
  44 + > * 【用户】关联小区,调【小区】接口。
  45 +
37 ## 物业管理 46 ## 物业管理
38 **物业公告** 47 **物业公告**
39 > * 已发布的公告不可以被删除、修改。 48 > * 已发布的公告不可以被删除、修改。
40 - > * 查看详情时表单不能编辑,禁用表单会把按钮也禁用掉,所以单列出来一个返回按钮。  
41 \ No newline at end of file 49 \ No newline at end of file
  50 + > * 查看详情时表单不能编辑,禁用表单会把按钮也禁用掉,所以单列出来一个返回按钮。
  51 +
  52 +## 活动管理
  53 + **活动列表**
  54 + > * 添加活动时,被禁用的活动分类不可以被选择。
  55 + > * 要验证活动结束时间晚于活动开始时间,报名结束时间要晚于报名开始时间,没有验证和【现在】时间的前后关系。
42 \ No newline at end of file 56 \ No newline at end of file
src/api/community/residence.ts
@@ -31,4 +31,12 @@ export function allNeighborhood() { @@ -31,4 +31,12 @@ export function allNeighborhood() {
31 method: 'get', 31 method: 'get',
32 url: '/neighborhood/allList' 32 url: '/neighborhood/allList'
33 }) 33 })
  34 +}
  35 +
  36 +// 机构下小区
  37 +export function getPropertyNbhds () {
  38 + return request({
  39 + method: 'get',
  40 + url: '/neighborhood/getPropertyNbhds'
  41 + })
34 } 42 }
35 \ No newline at end of file 43 \ No newline at end of file
src/api/event/index.ts
@@ -104,4 +104,30 @@ export const eventCategory = async ( params: any ) =&gt; { @@ -104,4 +104,30 @@ export const eventCategory = async ( params: any ) =&gt; {
104 params: params 104 params: params
105 }) 105 })
106 return res 106 return res
  107 +}
  108 +
  109 +/**
  110 + * @description 报名信息
  111 + * @function signupList
  112 + */
  113 +export const signupList = async (params: any) => {
  114 + let res: any = await request({
  115 + method: 'get',
  116 + url: '/signup/signupListByHandworkId',
  117 + params: params
  118 + })
  119 + return res
  120 +}
  121 +
  122 +/**
  123 + * @description 报名信息
  124 + * @function cancelSignup
  125 + */
  126 + export const cancelSignup = async (params: any) => {
  127 + let res: any = await request({
  128 + method: 'post',
  129 + url: '/signup/cancelSignup',
  130 + params: params
  131 + })
  132 + return res
107 } 133 }
108 \ No newline at end of file 134 \ No newline at end of file
src/components/Photowall/index.vue 0 → 100644
  1 +<script setup lang="ts">
  2 +/**
  3 + * 多图上传组件
  4 + * @module Photowall
  5 + */
  6 +import { ref, reactive } from "vue";
  7 +import { useLoginStore } from "@/pinia/login";
  8 +import { ElMessage } from "element-plus";
  9 +import { Plus } from "@element-plus/icons-vue";
  10 +import type {
  11 + UploadFile,
  12 + ElFile,
  13 + ElUploadProgressEvent,
  14 +} from "element-plus/es/components/upload/src/upload.type";
  15 +/**
  16 + * @description 组件属性
  17 + * @prop {string | null} tagName 标签
  18 + * @prop {string} moduleName 上传接口需要传的module值
  19 + * @prop {number} limit 图片数量上限
  20 + * @prop {string} tip 上传须知
  21 + * @prop {array} fileList 默认显示的图片
  22 + * @prop {array<string>} formats 允许上传的图片格式
  23 + * @prop {number | null} maxSize 允许上传的最大图片尺寸 default = 1 means 1MB
  24 + */
  25 +interface Props {
  26 + tagName?: string;
  27 + moduleName?: string;
  28 + limit?: number;
  29 + maxSize?: number;
  30 + formats?: string[];
  31 + tip?: string;
  32 + fileList?: string[];
  33 +}
  34 +const props = withDefaults(defineProps<Props>(), {
  35 + tagName: "",
  36 + moduleName: "test",
  37 + limit: 9,
  38 + maxSize: 1,
  39 + fileList: () => [],
  40 + formats: () => [
  41 + "image/jpeg",
  42 + "image/gif",
  43 + "image/png",
  44 + "image/x-icon",
  45 + "image/svg+xml",
  46 + "image/webp",
  47 + ],
  48 + tip: "最多可以上传9张图片,单张图片大小不可超过1MB",
  49 +});
  50 +const dialogImageUrl = ref("");
  51 +const dialogVisible = ref(false);
  52 +/**
  53 + * @description 上传图片接口配置
  54 + */
  55 +const uploadSettings = reactive({
  56 + uploadUrl: `${import.meta.env.VITE_BASE_URL}upload/uploadPicSource?module=${
  57 + props.moduleName
  58 + }`,
  59 + headers: {
  60 + type: "formData",
  61 + "X-Token": useLoginStore()?.getToken,
  62 + },
  63 +});
  64 +/**
  65 + * @method handlePictureCardPreview
  66 + * @description 已上传图片大图预览
  67 + * @param {UploadFile} file 文件对象
  68 + */
  69 +const handlePictureCardPreview = (file: UploadFile) => {
  70 + dialogImageUrl.value = file?.response?.data;
  71 + dialogVisible.value = true;
  72 +};
  73 +/**
  74 + * @description 图片数量超上限提示
  75 + */
  76 +const handleExceed = () => {
  77 + ElMessage.error(`最多可以传${props.limit}张图片`);
  78 +};
  79 +/**
  80 + * @method beforeAvatarUpload
  81 + * @description 图片上传之前检查格式、最大尺寸
  82 + * @param {ElFile} file 文件对象
  83 + */
  84 +const beforeAvatarUpload = (file: ElFile) => {
  85 + const isFormatAllowed = props.formats.includes(file.type);
  86 + const isSizeAllowed = file.size / 1024 / 1024 < props.maxSize;
  87 + if (!isFormatAllowed) {
  88 + ElMessage.error("图片格式不支持");
  89 + }
  90 + if (!isSizeAllowed) {
  91 + ElMessage.error("图片尺寸过大");
  92 + }
  93 + return isFormatAllowed && isSizeAllowed;
  94 +};
  95 +/**
  96 + * @method handleAvatarSuccess
  97 + * @description 图片上传成功
  98 + * @param {object} res 接口返回信息
  99 + * @param {object} file 当前文件
  100 + * @param {object} fileList 上传成功的文件列表
  101 + */
  102 +const handleAvatarSuccess = (
  103 + res: ElUploadProgressEvent,
  104 + file: ElFile,
  105 + fileList: ElFile[]
  106 +) => {
  107 + console.log(fileList)
  108 + emit(
  109 + "finish",
  110 + fileList.map((item) => item.response? item.response.data: item.url),
  111 + props.tagName
  112 + );
  113 +};
  114 +/**
  115 + * @method handleRemove
  116 + * @description 图片移除
  117 + * @param {object} file 当前文件
  118 + * @param {object} fileList 上传成功的文件列表
  119 + */
  120 +const handleRemove = (file: ElFile, fileList: ElFile[]) => {
  121 + emit(
  122 + "finish",
  123 + fileList.map((item) => item.response? item.response.data: item.url),
  124 + props.tagName
  125 + );
  126 +};
  127 +const emit = defineEmits<{
  128 + (e: "finish", images: string, tagName: string): void;
  129 +}>();
  130 +</script>
  131 +
  132 +<template>
  133 + <el-upload
  134 + :action="uploadSettings.uploadUrl"
  135 + :headers="uploadSettings.headers"
  136 + :with-credentials="true"
  137 + :limit="props.limit"
  138 + name="multipartFile"
  139 + list-type="picture-card"
  140 + :file-list="props.fileList"
  141 + :on-preview="handlePictureCardPreview"
  142 + :on-exceed="handleExceed"
  143 + :on-success="handleAvatarSuccess"
  144 + :on-remove="handleRemove"
  145 + :before-upload="beforeAvatarUpload"
  146 + >
  147 + <el-icon><plus /></el-icon>
  148 + </el-upload>
  149 + <div class="tip">{{ props.tip }}</div>
  150 + <el-dialog v-model="dialogVisible" title="图片预览">
  151 + <div style="text-align: center">
  152 + <el-image
  153 + :src="dialogImageUrl"
  154 + fit="contain"
  155 + style="height: 500px"
  156 + ></el-image>
  157 + </div>
  158 + </el-dialog>
  159 +</template>
src/router/modules/event.ts
@@ -7,17 +7,22 @@ const event = { @@ -7,17 +7,22 @@ const event = {
7 path: '/event/category', 7 path: '/event/category',
8 name: 'eventCategory', 8 name: 'eventCategory',
9 component: () => import('@/views/event/category/index.vue'), 9 component: () => import('@/views/event/category/index.vue'),
10 - meta: { title: '公益分类' } 10 + meta: { title: '活动类型' }
11 }, { 11 }, {
12 path: '/event/handwork', 12 path: '/event/handwork',
13 name: 'handwork', 13 name: 'handwork',
14 component: () => import('@/views/event/handwork/index.vue'), 14 component: () => import('@/views/event/handwork/index.vue'),
15 - meta: { title: '手工活动' } 15 + meta: { title: '活动列表' }
16 }, { 16 }, {
17 path: '/event/handwork/edit', 17 path: '/event/handwork/edit',
18 name: 'handworkEdit', 18 name: 'handworkEdit',
19 component: () => import('@/views/event/handwork/edit.vue'), 19 component: () => import('@/views/event/handwork/edit.vue'),
20 - meta: { title: '手工活动编辑' } 20 + meta: { title: '活动编辑' }
  21 + }, {
  22 + path: '/event/signup',
  23 + name: 'signup',
  24 + component: () => import('@/views/event/handwork/signup.vue'),
  25 + meta: { title: '报名信息' }
21 }, { 26 }, {
22 path: '/event/feedback', 27 path: '/event/feedback',
23 name: 'feedback', 28 name: 'feedback',
src/views/event/handwork/edit.vue
1 <script setup lang="ts"> 1 <script setup lang="ts">
2 -import { reactive, ref, getCurrentInstance, onMounted } from "vue"; 2 +import { reactive, ref, getCurrentInstance, onMounted, nextTick } from "vue";
3 import { eventCategory, handworkEdit } from "@/api/event"; 3 import { eventCategory, handworkEdit } from "@/api/event";
4 import { useRoute } from "vue-router"; 4 import { useRoute } from "vue-router";
5 import { back } from "@/utils/tool"; 5 import { back } from "@/utils/tool";
6 -// import * as store from "@/pinia"; 6 +import { getPropertyNbhds } from "@/api/community/residence";
7 import { useLoginStore } from "@/pinia/login"; 7 import { useLoginStore } from "@/pinia/login";
  8 +import Photowall from "@/components/Photowall/index.vue";
8 import type { ElForm } from "element-plus"; 9 import type { ElForm } from "element-plus";
9 let form = reactive({ 10 let form = reactive({
10 data: { 11 data: {
11 name: "", 12 name: "",
12 craftId: null, 13 craftId: null,
13 startTime: "", 14 startTime: "",
  15 + endTime: "",
  16 + signupStartTime: "",
  17 + signupEndTime: "",
14 duration: null, 18 duration: null,
15 location: "", 19 location: "",
16 unitPrice: null, 20 unitPrice: null,
@@ -21,14 +25,71 @@ let form = reactive({ @@ -21,14 +25,71 @@ let form = reactive({
21 personLimit: null, 25 personLimit: null,
22 publicityPic: "", 26 publicityPic: "",
23 status: 0, 27 status: 0,
  28 + processDesc: "",
  29 + neighborhoodId: "",
24 }, 30 },
  31 + publicityPic: [],
25 category: [], 32 category: [],
  33 + communities: [],
  34 + communityList: [],
  35 + value1: [],
  36 + value2: [],
26 dataType: "", 37 dataType: "",
27 loading: false, 38 loading: false,
28 }); 39 });
29 const ruleFormRef = ref<InstanceType<typeof ElForm>>(); 40 const ruleFormRef = ref<InstanceType<typeof ElForm>>();
30 let instance: ComponentInternalInstance | null = getCurrentInstance(); 41 let instance: ComponentInternalInstance | null = getCurrentInstance();
31 /** 42 /**
  43 + * 结束时间要晚于开始时间
  44 + */
  45 +// const checkStartTime = (rules, value, callback) => {
  46 +// if (checkTime(value, form.data.endTime)) {
  47 +// callback();
  48 +// } else {
  49 +// callback(new Error("结束时间要晚于开始时间"));
  50 +// }
  51 +// };
  52 +// const checkEndTime = (rules, value, callback) => {
  53 +// if (checkTime(form.data.startTime, value)) {
  54 +// callback();
  55 +// } else {
  56 +// callback(new Error("结束时间要晚于开始时间"));
  57 +// }
  58 +// };
  59 +// const checkSignUpStartTime = (rules, value, callback) => {
  60 +// if (checkTime(value, form.data.signupEndTime)) {
  61 +// callback();
  62 +// } else {
  63 +// callback(new Error("报名结束时间要晚于报名开始时间"));
  64 +// }
  65 +// };
  66 +// const checkSignUpEndTime = (rules, value, callback) => {
  67 +// if (checkTime(form.data.signupStartTime, value)) {
  68 +// callback();
  69 +// } else {
  70 +// callback(new Error("报名结束时间要晚于报名开始时间"));
  71 +// }
  72 +// };
  73 +// const checkTime = (startTime, endTime, isAfterNow = false) => {
  74 +// if (new Date(endTime).getTime() > new Date(startTime).getTime()) {
  75 +// return true;
  76 +// } else {
  77 +// return false;
  78 +// }
  79 +// };
  80 +/**
  81 + * 时间组件回调
  82 + * @param {array} value [开始时间, 结束时间]
  83 + */
  84 +const handleTimeChange = (value: array) => {
  85 + form.data.startTime = value ? value[0] : "";
  86 + form.data.endTime = value ? value[1] : "";
  87 +};
  88 +const handleSignupTimeChange = (value: array) => {
  89 + form.data.signupStartTime = value ? value[0] : "";
  90 + form.data.signupEndTime = value ? value[1] : "";
  91 +};
  92 +/**
32 * 表单验证规则 93 * 表单验证规则
33 */ 94 */
34 const rules = reactive({ 95 const rules = reactive({
@@ -49,8 +110,33 @@ const rules = reactive({ @@ -49,8 +110,33 @@ const rules = reactive({
49 startTime: [ 110 startTime: [
50 { 111 {
51 required: true, 112 required: true,
52 - message: "请选择活动开始时间", 113 + message: "结束时间要晚于开始时间",
53 trigger: "change", 114 trigger: "change",
  115 + // validator: checkStartTime,
  116 + },
  117 + ],
  118 + endTime: [
  119 + {
  120 + required: true,
  121 + message: "结束时间要晚于开始时间",
  122 + trigger: "change",
  123 + // validator: checkEndTime,
  124 + },
  125 + ],
  126 + signupStartTime: [
  127 + {
  128 + required: true,
  129 + message: "报名结束时间要晚于报名开始时间",
  130 + trigger: "change",
  131 + // validator: checkSignUpStartTime,
  132 + },
  133 + ],
  134 + signupEndTime: [
  135 + {
  136 + required: true,
  137 + message: "报名结束时间要晚于报名开始时间",
  138 + trigger: "change",
  139 + // validator: checkSignUpEndTime,
54 }, 140 },
55 ], 141 ],
56 duration: [ 142 duration: [
@@ -77,7 +163,7 @@ const rules = reactive({ @@ -77,7 +163,7 @@ const rules = reactive({
77 description: [ 163 description: [
78 { 164 {
79 required: true, 165 required: true,
80 - message: "请填写活动内容", 166 + message: "请填写活动简介",
81 trigger: "change", 167 trigger: "change",
82 }, 168 },
83 ], 169 ],
@@ -100,6 +186,7 @@ const submitForm = ( @@ -100,6 +186,7 @@ const submitForm = (
100 if (!formEl) return; 186 if (!formEl) return;
101 formEl.validate(async (valid) => { 187 formEl.validate(async (valid) => {
102 if (valid) { 188 if (valid) {
  189 + form.data.publicityPic = form.publicityPic.map(item => item.url).join(',')
103 handworkEdit(form.data) 190 handworkEdit(form.data)
104 .then((res) => { 191 .then((res) => {
105 if (res) { 192 if (res) {
@@ -131,7 +218,6 @@ const getCategory = async (pageSize: number = 20) =&gt; { @@ -131,7 +218,6 @@ const getCategory = async (pageSize: number = 20) =&gt; {
131 const res = await eventCategory({ 218 const res = await eventCategory({
132 page: 1, 219 page: 1,
133 pageSize: pageSize, 220 pageSize: pageSize,
134 - // oid: store?.family?.loginStore()?.organizationId ?? 0,  
135 oId: useLoginStore()?.getOid ?? 0, 221 oId: useLoginStore()?.getOid ?? 0,
136 }); 222 });
137 form.category = res?.data?.data?.list; 223 form.category = res?.data?.data?.list;
@@ -142,14 +228,48 @@ const getCategory = async (pageSize: number = 20) =&gt; { @@ -142,14 +228,48 @@ const getCategory = async (pageSize: number = 20) =&gt; {
142 console.log(e); 228 console.log(e);
143 } 229 }
144 }; 230 };
  231 +/**
  232 + * 机构下小区列表
  233 + */
  234 +const getCommunityList = async () => {
  235 + try {
  236 + const res = await getPropertyNbhds();
  237 + form.communities = res?.data?.data;
  238 + } catch (e) {
  239 + console.log(e);
  240 + }
  241 +};
  242 +/**
  243 + * 多图上传组件回调
  244 + * @param {string} images 回调的图片urls
  245 + * @param {string} tagName 标签
  246 + */
  247 +const handleFinish = (images) => {
  248 + form.publicityPic = [];
  249 + setTimeout(() => {
  250 + images.map((item) => {
  251 + form.publicityPic.push({
  252 + url: item,
  253 + });
  254 + });
  255 + }, 500);
  256 +};
145 onMounted(() => { 257 onMounted(() => {
146 - getCategory() 258 + getCategory();
  259 + getCommunityList();
147 if (JSON.stringify(useRoute().query) === "{}") { 260 if (JSON.stringify(useRoute().query) === "{}") {
148 form.dataType = "add"; 261 form.dataType = "add";
149 } else { 262 } else {
150 form.dataType = "edit"; 263 form.dataType = "edit";
151 - form.data = useRoute().query  
152 - form.data.craftId = ~~useRoute().query.craftId 264 + form.data = useRoute().query;
  265 + form.data.craftId = ~~useRoute().query.craftId;
  266 + useRoute()
  267 + .query.publicityPic.split(",")
  268 + .map((item) => {
  269 + form.publicityPic.push({
  270 + url: item,
  271 + });
  272 + });
153 } 273 }
154 }); 274 });
155 </script> 275 </script>
@@ -157,8 +277,8 @@ onMounted(() =&gt; { @@ -157,8 +277,8 @@ onMounted(() =&gt; {
157 <template> 277 <template>
158 <div class="page-container"> 278 <div class="page-container">
159 <el-card class="form_card" style="max-width: 1303px"> 279 <el-card class="form_card" style="max-width: 1303px">
160 - <h1 v-show="form.dataType === 'add'">新增手工活动</h1>  
161 - <h1 v-show="form.dataType === 'edit'">编辑手工活动</h1> 280 + <h1 v-show="form.dataType === 'add'">新增活动</h1>
  281 + <h1 v-show="form.dataType === 'edit'">编辑活动</h1>
162 <el-form 282 <el-form
163 :inline="true" 283 :inline="true"
164 :model="form.data" 284 :model="form.data"
@@ -175,12 +295,19 @@ onMounted(() =&gt; { @@ -175,12 +295,19 @@ onMounted(() =&gt; {
175 maxlength="15" 295 maxlength="15"
176 /> 296 />
177 </el-form-item> 297 </el-form-item>
178 - <el-form-item label="活动分类" prop="craftId" style="width: 50%"> 298 + <el-form-item label="活动分类" prop="craftId" style="width: 100%">
  299 + <!-- 被禁用了的活动分类不可以选择 -->
179 <el-select v-model="form.data.craftId" placeholder="请选择活动分类"> 300 <el-select v-model="form.data.craftId" placeholder="请选择活动分类">
180 - <el-option v-for="(item, index) in form.category" :key="index" :label="item.name" :value="item.id"></el-option> 301 + <el-option
  302 + v-for="(item, index) in form.category"
  303 + :key="index"
  304 + :label="item.name"
  305 + :value="item.id"
  306 + :disabled="!item.status"
  307 + ></el-option>
181 </el-select> 308 </el-select>
182 </el-form-item> 309 </el-form-item>
183 - <el-form-item label="开始时间" prop="startTime" style="width: 50%"> 310 + <!-- <el-form-item label="开始时间" prop="startTime" style="width: 50%">
184 <el-date-picker 311 <el-date-picker
185 v-model="form.data.startTime" 312 v-model="form.data.startTime"
186 type="datetime" 313 type="datetime"
@@ -189,6 +316,63 @@ onMounted(() =&gt; { @@ -189,6 +316,63 @@ onMounted(() =&gt; {
189 > 316 >
190 </el-date-picker> 317 </el-date-picker>
191 </el-form-item> 318 </el-form-item>
  319 + <el-form-item label="结束时间" prop="endTime" style="width: 50%">
  320 + <el-date-picker
  321 + v-model="form.data.endTime"
  322 + type="datetime"
  323 + format="YYYY-MM-DD HH:mm:ss"
  324 + placeholder="请选择结束时间"
  325 + >
  326 + </el-date-picker>
  327 + </el-form-item> -->
  328 + <el-form-item label="活动时间" prop="startTime" style="width: 100%">
  329 + <el-date-picker
  330 + v-model="form.value1"
  331 + type="datetimerange"
  332 + range-separator="至"
  333 + format="YYYY-MM-DD HH:mm:ss"
  334 + start-placeholder="开始时间"
  335 + end-placeholder="结束时间"
  336 + @change="handleTimeChange"
  337 + ></el-date-picker>
  338 + </el-form-item>
  339 + <el-form-item label="报名时间" prop="signupStartTime" style="width: 100%">
  340 + <el-date-picker
  341 + v-model="form.value2"
  342 + type="datetimerange"
  343 + range-separator="至"
  344 + format="YYYY-MM-DD HH:mm:ss"
  345 + start-placeholder="报名开始时间"
  346 + end-placeholder="报名结束时间"
  347 + @change="handleSignupTimeChange"
  348 + ></el-date-picker>
  349 + </el-form-item>
  350 + <!-- <el-form-item
  351 + label="报名开始时间"
  352 + prop="signupStartTime"
  353 + style="width: 50%"
  354 + >
  355 + <el-date-picker
  356 + v-model="form.data.signupStartTime"
  357 + type="datetime"
  358 + format="YYYY-MM-DD HH:mm:ss"
  359 + placeholder="请选择报名开始时间"
  360 + >
  361 + </el-date-picker>
  362 + </el-form-item>
  363 + <el-form-item
  364 + label="报名结束时间"
  365 + prop="signupEndTime"
  366 + style="width: 50%"
  367 + >
  368 + <el-date-picker
  369 + v-model="form.data.signupEndTime"
  370 + type="datetime"
  371 + format="YYYY-MM-DD HH:mm:ss"
  372 + placeholder="请选择报名结束时间"
  373 + >
  374 + </el-date-picker>
  375 + </el-form-item> -->
192 <el-form-item label="活动时长" prop="duration" style="width: 50%"> 376 <el-form-item label="活动时长" prop="duration" style="width: 50%">
193 <el-input 377 <el-input
194 v-model.trim="form.data.duration" 378 v-model.trim="form.data.duration"
@@ -212,10 +396,20 @@ onMounted(() =&gt; { @@ -212,10 +396,20 @@ onMounted(() =&gt; {
212 maxlength="15" 396 maxlength="15"
213 /> 397 />
214 </el-form-item> 398 </el-form-item>
215 - <el-form-item label="活动内容" prop="description" style="width: 100%"> 399 + <el-form-item label="活动简介" prop="description" style="width: 100%">
216 <el-input 400 <el-input
217 v-model.trim="form.data.description" 401 v-model.trim="form.data.description"
218 - placeholder="请填写活动内容" 402 + placeholder="请填写活动简介"
  403 + maxlength="1500"
  404 + show-word-limit
  405 + :rows="5"
  406 + type="textarea"
  407 + />
  408 + </el-form-item>
  409 + <el-form-item label="流程介绍" prop="processDesc" style="width: 100%">
  410 + <el-input
  411 + v-model.trim="form.data.processDesc"
  412 + placeholder="请填写流程介绍"
219 maxlength="1500" 413 maxlength="1500"
220 show-word-limit 414 show-word-limit
221 :rows="5" 415 :rows="5"
@@ -236,6 +430,27 @@ onMounted(() =&gt; { @@ -236,6 +430,27 @@ onMounted(() =&gt; {
236 maxlength="15" 430 maxlength="15"
237 /> 431 />
238 </el-form-item> 432 </el-form-item>
  433 + <el-form-item label="宣传图片" prop="publicityPic" style="width: 100%">
  434 + <Photowall
  435 + @finish="handleFinish"
  436 + :fileList="form.publicityPic"
  437 + ></Photowall>
  438 + </el-form-item>
  439 + <el-form-item label="小区" prop="neighborhoodId" style="width: 100%">
  440 + <el-checkbox-group
  441 + v-model="form.communityList"
  442 + @change="(data) => (form.data.neighborhoodIds = data.join(','))"
  443 + v-if="form.communities.length"
  444 + >
  445 + <el-checkbox
  446 + v-for="(item, index) in form.communities"
  447 + :key="index"
  448 + :label="item.id"
  449 + >{{ item.name }}</el-checkbox
  450 + >
  451 + </el-checkbox-group>
  452 + <span class="tip" v-else>暂无小区</span>
  453 + </el-form-item>
239 <el-form-item style="width: 100%" v-show="form.dataType !== 'detail'"> 454 <el-form-item style="width: 100%" v-show="form.dataType !== 'detail'">
240 <el-button 455 <el-button
241 type="primary" 456 type="primary"
src/views/event/handwork/index.vue
@@ -3,6 +3,7 @@ import { reactive, ref, onMounted } from &quot;vue&quot;; @@ -3,6 +3,7 @@ import { reactive, ref, onMounted } from &quot;vue&quot;;
3 import { handworkList } from "@/api/event"; 3 import { handworkList } from "@/api/event";
4 import { parseTime } from "@/utils/tool"; 4 import { parseTime } from "@/utils/tool";
5 import { statusData } from "./../config"; 5 import { statusData } from "./../config";
  6 +import { useLoginStore } from "@/pinia/login";
6 import Pagination from "@/components/Pagination/index.vue"; 7 import Pagination from "@/components/Pagination/index.vue";
7 import { ElMessageBox, ElMessage } from "element-plus"; 8 import { ElMessageBox, ElMessage } from "element-plus";
8 interface Form { 9 interface Form {
@@ -33,7 +34,7 @@ let data = reactive({ @@ -33,7 +34,7 @@ let data = reactive({
33 query: { 34 query: {
34 page: 1, 35 page: 1,
35 pageSize: 10, 36 pageSize: 10,
36 - oid: 0, 37 + oid: useLoginStore()?.getOid ?? 0,
37 startTime: "", 38 startTime: "",
38 endTime: "", 39 endTime: "",
39 name: "", 40 name: "",
src/views/event/handwork/signup.vue 0 → 100644
  1 +<template>
  2 + 报名信息
  3 +</template>
0 \ No newline at end of file 4 \ No newline at end of file