edit.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  1. <template>
  2. <div class="performance-edit-page">
  3. <div class="page-header">
  4. <div class="header-left" @click="goBack">
  5. <el-icon class="back-icon">
  6. <ArrowLeft />
  7. </el-icon>
  8. <span class="back-text">返回</span>
  9. </div>
  10. <h1 class="page-title">
  11. {{ viewMode ? "详情" : id ? "编辑" : "新建" }}
  12. </h1>
  13. <el-button v-if="viewMode" type="primary" @click="goEdit"> 编辑 </el-button>
  14. <div v-else class="header-right" @click="goBack">
  15. <el-icon class="close-icon">
  16. <Close />
  17. </el-icon>
  18. </div>
  19. </div>
  20. <div class="page-content">
  21. <el-form
  22. ref="formRef"
  23. :model="form"
  24. :rules="formRules"
  25. label-width="120px"
  26. class="performance-form two-column-form"
  27. @submit.prevent
  28. >
  29. <el-row :gutter="24">
  30. <el-col :span="12">
  31. <el-form-item label="演出名称" prop="name" required>
  32. <el-input
  33. v-model="form.name"
  34. placeholder="请输入"
  35. maxlength="20"
  36. show-word-limit
  37. clearable
  38. :disabled="viewMode"
  39. class="form-input"
  40. />
  41. </el-form-item>
  42. <el-form-item label="演出海报" required>
  43. <div class="upload-wrap">
  44. <UploadImgs
  45. v-model:file-list="posterFileList"
  46. :api="uploadImgStore"
  47. :limit="1"
  48. :file-size="5"
  49. :disabled="viewMode"
  50. class="poster-upload"
  51. @update:file-list="onPosterChange"
  52. />
  53. <span class="upload-tip">({{ posterFileList.length }}/1)</span>
  54. </div>
  55. </el-form-item>
  56. <el-form-item label="演出风格" required>
  57. <el-checkbox-group v-model="form.style" :disabled="viewMode">
  58. <el-checkbox v-for="opt in styleOptions" :key="opt" :label="opt">
  59. {{ opt }}
  60. </el-checkbox>
  61. </el-checkbox-group>
  62. </el-form-item>
  63. <el-form-item label="演出类型">
  64. <el-radio-group v-model="form.performanceType" :disabled="viewMode">
  65. <el-radio value="特邀演出"> 特邀演出 </el-radio>
  66. <el-radio value="常规演出"> 常规演出 </el-radio>
  67. </el-radio-group>
  68. <div class="form-tip">特邀演出为单次</div>
  69. </el-form-item>
  70. <el-form-item label="演出频次">
  71. <el-radio-group v-model="form.frequency" :disabled="viewMode">
  72. <el-radio value="单次"> 单次 </el-radio>
  73. <el-radio value="每天定时进行" :disabled="form.performanceType === '特邀演出'"> 每天定时进行 </el-radio>
  74. <el-radio value="每周定时进行" :disabled="form.performanceType === '特邀演出'"> 每周定时进行 </el-radio>
  75. </el-radio-group>
  76. </el-form-item>
  77. <template v-if="form.frequency === '单次'">
  78. <el-form-item label="演出时间" required>
  79. <div class="date-time-row">
  80. <el-date-picker
  81. v-model="singleStartDate"
  82. type="date"
  83. placeholder="年/月/日"
  84. value-format="YYYY-MM-DD"
  85. style="width: 140px"
  86. :disabled="viewMode"
  87. />
  88. <el-time-picker
  89. v-model="singleStartTime"
  90. format="HH:mm"
  91. value-format="HH:mm"
  92. placeholder="--:--"
  93. style="width: 100px"
  94. :disabled="viewMode"
  95. />
  96. <span class="sep">至</span>
  97. <el-date-picker
  98. v-model="singleEndDate"
  99. type="date"
  100. placeholder="年/月/日"
  101. value-format="YYYY-MM-DD"
  102. style="width: 140px"
  103. :disabled="viewMode"
  104. />
  105. <el-time-picker
  106. v-model="singleEndTime"
  107. format="HH:mm"
  108. value-format="HH:mm"
  109. placeholder="--:--"
  110. style="width: 100px"
  111. :disabled="viewMode"
  112. />
  113. </div>
  114. </el-form-item>
  115. </template>
  116. <template v-if="form.frequency === '每天定时进行'">
  117. <el-form-item label="演出日期" required>
  118. <div class="date-time-row">
  119. <el-date-picker
  120. v-model="dailyDateStart"
  121. type="date"
  122. placeholder="年/月/日"
  123. value-format="YYYY-MM-DD"
  124. style="width: 140px"
  125. :disabled="viewMode"
  126. />
  127. <span class="sep">至</span>
  128. <el-date-picker
  129. v-model="dailyDateEnd"
  130. type="date"
  131. placeholder="年/月/日"
  132. value-format="YYYY-MM-DD"
  133. style="width: 140px"
  134. :disabled="viewMode"
  135. />
  136. </div>
  137. </el-form-item>
  138. <el-form-item label="演出时间" required>
  139. <div class="date-time-row">
  140. <el-time-picker
  141. v-model="dailyTimeStart"
  142. format="HH:mm"
  143. value-format="HH:mm"
  144. placeholder="--:--"
  145. style="width: 100px"
  146. :disabled="viewMode"
  147. />
  148. <span class="sep">至</span>
  149. <el-time-picker
  150. v-model="dailyTimeEnd"
  151. format="HH:mm"
  152. value-format="HH:mm"
  153. placeholder="--:--"
  154. style="width: 100px"
  155. :disabled="viewMode"
  156. />
  157. </div>
  158. </el-form-item>
  159. </template>
  160. <template v-if="form.frequency === '每周定时进行'">
  161. <el-form-item label="演出日期">
  162. <el-checkbox-group v-model="form.weeklyPerformanceWeekdays" :disabled="viewMode">
  163. <el-checkbox v-for="day in weekdays" :key="day" :label="day">
  164. {{ day }}
  165. </el-checkbox>
  166. </el-checkbox-group>
  167. </el-form-item>
  168. <el-form-item label="演出日期" required>
  169. <div class="date-time-row">
  170. <el-date-picker
  171. v-model="weeklyDateStart"
  172. type="date"
  173. placeholder="年/月/日"
  174. value-format="YYYY-MM-DD"
  175. style="width: 140px"
  176. :disabled="viewMode"
  177. />
  178. <span class="sep">至</span>
  179. <el-date-picker
  180. v-model="weeklyDateEnd"
  181. type="date"
  182. placeholder="年/月/日"
  183. value-format="YYYY-MM-DD"
  184. style="width: 140px"
  185. :disabled="viewMode"
  186. />
  187. </div>
  188. </el-form-item>
  189. <el-form-item label="演出时间" required>
  190. <div class="date-time-row">
  191. <el-time-picker
  192. v-model="weeklyTimeStart"
  193. format="HH:mm"
  194. value-format="HH:mm"
  195. placeholder="--:--"
  196. style="width: 100px"
  197. :disabled="viewMode"
  198. />
  199. <span class="sep">至</span>
  200. <el-time-picker
  201. v-model="weeklyTimeEnd"
  202. format="HH:mm"
  203. value-format="HH:mm"
  204. placeholder="--:--"
  205. style="width: 100px"
  206. :disabled="viewMode"
  207. />
  208. </div>
  209. </el-form-item>
  210. </template>
  211. <el-form-item label="图文详情图片">
  212. <div class="upload-wrap">
  213. <UploadImgs
  214. v-model:file-list="detailImageFileList"
  215. :api="uploadImgStore"
  216. :limit="9"
  217. :file-size="5"
  218. :disabled="viewMode"
  219. class="detail-upload"
  220. @update:file-list="onDetailImagesChange"
  221. />
  222. <span class="upload-tip">({{ form.detailPicUrl.length }}/9)</span>
  223. </div>
  224. </el-form-item>
  225. <el-form-item label="图文详情描述">
  226. <el-input
  227. v-model="form.detailDescription"
  228. type="textarea"
  229. placeholder="请输入"
  230. :rows="3"
  231. maxlength="300"
  232. show-word-limit
  233. :disabled="viewMode"
  234. class="form-textarea"
  235. />
  236. </el-form-item>
  237. </el-col>
  238. <el-col :span="12">
  239. <el-form-item label="表演嘉宾">
  240. <el-link v-if="!viewMode" type="primary" @click="openGuestSelect"> 请添加 </el-link>
  241. <div v-if="form.guests?.length" class="guest-list">
  242. <div v-for="g in form.guests" :key="String(g.id)" class="guest-item">
  243. <el-avatar :size="32" :src="g.avatar">
  244. <el-icon><User /></el-icon>
  245. </el-avatar>
  246. <span class="guest-name">{{ g.name || g.nickname || "--" }} {{ g.position ? ` ${g.position}` : "" }}</span>
  247. <el-icon v-if="!viewMode" class="guest-remove" @click="removeGuest(g)">
  248. <Close />
  249. </el-icon>
  250. </div>
  251. </div>
  252. </el-form-item>
  253. <el-form-item label="演出须知">
  254. <el-input
  255. v-model="form.notes"
  256. type="textarea"
  257. placeholder="请输入"
  258. :rows="6"
  259. maxlength="300"
  260. show-word-limit
  261. :disabled="viewMode"
  262. class="form-textarea"
  263. />
  264. </el-form-item>
  265. <!-- 详情模式:只读状态信息 -->
  266. <template v-if="viewMode">
  267. <el-form-item label="提交时间">
  268. <span class="view-only-value">{{ detailExtra.submitTime || "--" }}</span>
  269. </el-form-item>
  270. <el-form-item label="审核状态">
  271. <span class="view-only-value audit-status" :class="'audit-status--' + detailExtra.auditStatus">{{
  272. detailExtra.auditStatusLabel || "--"
  273. }}</span>
  274. </el-form-item>
  275. <el-form-item label="审核时间">
  276. <span class="view-only-value">{{ detailExtra.auditTime || "--" }}</span>
  277. </el-form-item>
  278. <el-form-item v-if="detailExtra.auditStatus === 2" label="拒绝原因">
  279. <div class="view-only-value reject-reason-text">
  280. {{ detailExtra.auditReason || "--" }}
  281. </div>
  282. </el-form-item>
  283. <el-form-item label="在线状态">
  284. <span class="view-only-value">{{ detailExtra.onlineStatusLabel || "--" }}</span>
  285. </el-form-item>
  286. </template>
  287. </el-col>
  288. </el-row>
  289. </el-form>
  290. </div>
  291. <div v-if="!viewMode" class="page-footer">
  292. <div class="footer-inner">
  293. <el-button @click="goBack"> 取消 </el-button>
  294. <el-button type="primary" :loading="submitting" @click="submit"> 提交 </el-button>
  295. </div>
  296. </div>
  297. <GuestSelectDialog
  298. v-model="guestSelectVisible"
  299. :selected-ids="selectedGuestIds"
  300. :selected-guests="form.guests"
  301. @confirm="onGuestsConfirm"
  302. />
  303. </div>
  304. </template>
  305. <script setup lang="ts" name="performanceEdit">
  306. import { ref, computed, watch, onMounted } from "vue";
  307. import { useRoute, useRouter } from "vue-router";
  308. import { ElMessage } from "element-plus";
  309. import { User, Close, ArrowLeft } from "@element-plus/icons-vue";
  310. import type { FormInstance, FormRules, UploadUserFile } from "element-plus";
  311. import UploadImgs from "@/components/Upload/Imgs.vue";
  312. import { uploadImgStore } from "@/api/modules/upload";
  313. import {
  314. getPerformanceDetail,
  315. saveOrUpdatePerformance,
  316. detailToFormModel,
  317. getDefaultFormModel,
  318. buildPerformanceBackendPayload,
  319. AUDIT_STATUS_LABEL
  320. } from "@/api/modules/performance";
  321. import GuestSelectDialog from "./components/GuestSelectDialog.vue";
  322. import type { GuestItem } from "./components/GuestSelectDialog.vue";
  323. const styleOptions = [
  324. "民谣",
  325. "爵士",
  326. "摇滚",
  327. "电音",
  328. "流行",
  329. "蓝调",
  330. "AXAPPELLA (全人声伴奏)",
  331. "SOUL",
  332. "朋克",
  333. "R&B",
  334. "EDM",
  335. "原创",
  336. "古典",
  337. "金属",
  338. "说唱"
  339. ];
  340. const weekdays = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"];
  341. const route = useRoute();
  342. const router = useRouter();
  343. const formRef = ref<FormInstance>();
  344. const id = ref<string>("");
  345. const viewMode = computed(() => route.query.mode === "detail");
  346. const submitting = ref(false);
  347. const posterFileList = ref<UploadUserFile[]>([]);
  348. const detailImageFileList = ref<UploadUserFile[]>([]);
  349. const guestSelectVisible = ref(false);
  350. const form = ref<Record<string, any>>(getDefaultFormModel());
  351. const detailExtra = ref<{
  352. submitTime: string;
  353. auditStatus: number;
  354. auditStatusLabel: string;
  355. auditTime: string;
  356. auditReason: string;
  357. onlineStatusLabel: string;
  358. }>({
  359. submitTime: "",
  360. auditStatus: 0,
  361. auditStatusLabel: "",
  362. auditTime: "",
  363. auditReason: "",
  364. onlineStatusLabel: ""
  365. });
  366. watch(
  367. () => form.value.performanceType,
  368. type => {
  369. if (type === "特邀演出") form.value.frequency = "单次";
  370. }
  371. );
  372. const singleStartDate = computed({
  373. get: () => form.value.performanceTime?.startDate ?? "",
  374. set: v => {
  375. if (!form.value.performanceTime) form.value.performanceTime = {};
  376. form.value.performanceTime.startDate = v;
  377. }
  378. });
  379. const singleStartTime = computed({
  380. get: () => form.value.performanceTime?.startTime ?? "",
  381. set: v => {
  382. if (!form.value.performanceTime) form.value.performanceTime = {};
  383. form.value.performanceTime.startTime = v;
  384. }
  385. });
  386. const singleEndDate = computed({
  387. get: () => form.value.performanceTime?.endDate ?? "",
  388. set: v => {
  389. if (!form.value.performanceTime) form.value.performanceTime = {};
  390. form.value.performanceTime.endDate = v;
  391. }
  392. });
  393. const singleEndTime = computed({
  394. get: () => form.value.performanceTime?.endTime ?? "",
  395. set: v => {
  396. if (!form.value.performanceTime) form.value.performanceTime = {};
  397. form.value.performanceTime.endTime = v;
  398. }
  399. });
  400. const dailyDateStart = computed({
  401. get: () => form.value.dailyPerformanceDateRange?.start ?? "",
  402. set: v => {
  403. if (!form.value.dailyPerformanceDateRange) form.value.dailyPerformanceDateRange = {};
  404. form.value.dailyPerformanceDateRange.start = v;
  405. }
  406. });
  407. const dailyDateEnd = computed({
  408. get: () => form.value.dailyPerformanceDateRange?.end ?? "",
  409. set: v => {
  410. if (!form.value.dailyPerformanceDateRange) form.value.dailyPerformanceDateRange = {};
  411. form.value.dailyPerformanceDateRange.end = v;
  412. }
  413. });
  414. const dailyTimeStart = computed({
  415. get: () => form.value.dailyPerformanceTimeRange?.start ?? "",
  416. set: v => {
  417. if (!form.value.dailyPerformanceTimeRange) form.value.dailyPerformanceTimeRange = {};
  418. form.value.dailyPerformanceTimeRange.start = v;
  419. }
  420. });
  421. const dailyTimeEnd = computed({
  422. get: () => form.value.dailyPerformanceTimeRange?.end ?? "",
  423. set: v => {
  424. if (!form.value.dailyPerformanceTimeRange) form.value.dailyPerformanceTimeRange = {};
  425. form.value.dailyPerformanceTimeRange.end = v;
  426. }
  427. });
  428. const weeklyDateStart = computed({
  429. get: () => form.value.weeklyPerformanceDateRange?.start ?? "",
  430. set: v => {
  431. if (!form.value.weeklyPerformanceDateRange) form.value.weeklyPerformanceDateRange = {};
  432. form.value.weeklyPerformanceDateRange.start = v;
  433. }
  434. });
  435. const weeklyDateEnd = computed({
  436. get: () => form.value.weeklyPerformanceDateRange?.end ?? "",
  437. set: v => {
  438. if (!form.value.weeklyPerformanceDateRange) form.value.weeklyPerformanceDateRange = {};
  439. form.value.weeklyPerformanceDateRange.end = v;
  440. }
  441. });
  442. const weeklyTimeStart = computed({
  443. get: () => form.value.weeklyPerformanceTimeRange?.start ?? "",
  444. set: v => {
  445. if (!form.value.weeklyPerformanceTimeRange) form.value.weeklyPerformanceTimeRange = {};
  446. form.value.weeklyPerformanceTimeRange.start = v;
  447. }
  448. });
  449. const weeklyTimeEnd = computed({
  450. get: () => form.value.weeklyPerformanceTimeRange?.end ?? "",
  451. set: v => {
  452. if (!form.value.weeklyPerformanceTimeRange) form.value.weeklyPerformanceTimeRange = {};
  453. form.value.weeklyPerformanceTimeRange.end = v;
  454. }
  455. });
  456. const selectedGuestIds = computed(() => form.value.guests?.map((g: any) => g.id) ?? []);
  457. const formRules: FormRules = {
  458. name: [{ required: true, message: "请输入演出名称", trigger: "blur" }]
  459. };
  460. onMounted(() => {
  461. id.value = (route.query.id as string) || "";
  462. if (id.value) loadDetail();
  463. else Object.assign(form.value, getDefaultFormModel());
  464. syncPosterAndDetailFiles();
  465. });
  466. async function loadDetail() {
  467. if (!id.value) return;
  468. try {
  469. const res: any = await getPerformanceDetail(id.value);
  470. const raw = res?.data ?? res;
  471. if (raw) {
  472. Object.assign(form.value, detailToFormModel(raw));
  473. detailExtra.value = {
  474. submitTime: raw.createdTime ?? raw.submitTime ?? raw.createTime ?? "",
  475. auditStatus: raw.reviewStatus ?? raw.auditStatus ?? 0,
  476. auditStatusLabel: AUDIT_STATUS_LABEL[raw.reviewStatus ?? raw.auditStatus] ?? "",
  477. auditTime: raw.auditTime ?? raw.reviewTime ?? "",
  478. auditReason: raw.rejectReason ?? raw.auditReason ?? "",
  479. onlineStatusLabel: (raw.onlineStatus ?? raw.shelfStatus) === 1 ? "上线" : "下线"
  480. };
  481. }
  482. syncPosterAndDetailFiles();
  483. } catch (e) {}
  484. }
  485. function syncPosterAndDetailFiles() {
  486. const poster = form.value.posterUrls?.[0] ?? form.value.imgUrl;
  487. posterFileList.value = poster ? ([{ name: "poster", url: poster }] as UploadUserFile[]) : [];
  488. const urls = form.value.detailPicUrl ?? [];
  489. detailImageFileList.value = urls.map((u: string, i: number) => ({ name: `detail-${i}`, url: u })) as UploadUserFile[];
  490. }
  491. function onPosterChange(list: UploadUserFile[]) {
  492. const url = list.length ? ((list[0].url as string) ?? "") : "";
  493. form.value.posterUrls = url ? [url] : [];
  494. form.value.imgUrl = url;
  495. }
  496. function onDetailImagesChange(list: UploadUserFile[]) {
  497. form.value.detailPicUrl = list.map(f => (typeof f.url === "string" ? f.url : "")).filter(Boolean);
  498. }
  499. function openGuestSelect() {
  500. guestSelectVisible.value = true;
  501. }
  502. function onGuestsConfirm(list: GuestItem[]) {
  503. form.value.guests = list;
  504. }
  505. function removeGuest(g: any) {
  506. form.value.guests = (form.value.guests || []).filter((x: any) => x.id !== g.id);
  507. }
  508. function goBack() {
  509. router.back();
  510. }
  511. function goEdit() {
  512. router.replace({ path: "/performance/edit", query: { id: id.value } });
  513. }
  514. function validateForm(): boolean {
  515. if (!form.value.name?.trim()) {
  516. ElMessage.warning("请输入演出名称");
  517. return false;
  518. }
  519. const poster = form.value.posterUrls?.[0] ?? form.value.imgUrl;
  520. if (!poster) {
  521. ElMessage.warning("请上传演出海报");
  522. return false;
  523. }
  524. if (!form.value.style?.length) {
  525. ElMessage.warning("请选择演出风格");
  526. return false;
  527. }
  528. if (form.value.frequency === "单次") {
  529. const pt = form.value.performanceTime || {};
  530. if (!pt.startDate || !pt.startTime || !pt.endDate || !pt.endTime) {
  531. ElMessage.warning("请填写演出时间");
  532. return false;
  533. }
  534. }
  535. if (form.value.frequency === "每天定时进行") {
  536. const dr = form.value.dailyPerformanceDateRange || {};
  537. const tr = form.value.dailyPerformanceTimeRange || {};
  538. if (!dr.start || !dr.end || !tr.start || !tr.end) {
  539. ElMessage.warning("请填写演出日期与时间");
  540. return false;
  541. }
  542. }
  543. if (form.value.frequency === "每周定时进行") {
  544. const wr = form.value.weeklyPerformanceDateRange || {};
  545. const tr = form.value.weeklyPerformanceTimeRange || {};
  546. if (!wr.start || !wr.end || !tr.start || !tr.end) {
  547. ElMessage.warning("请填写演出日期与时间");
  548. return false;
  549. }
  550. }
  551. return true;
  552. }
  553. async function submit() {
  554. if (!validateForm() || submitting.value) return;
  555. submitting.value = true;
  556. try {
  557. const payload = buildPerformanceBackendPayload(form.value);
  558. if (id.value) payload.id = id.value;
  559. const res: any = await saveOrUpdatePerformance(payload);
  560. if (res?.code === 200) {
  561. ElMessage.success(id.value ? "编辑成功" : "新建成功");
  562. router.back();
  563. } else {
  564. ElMessage.error(res?.msg || "提交失败");
  565. }
  566. } catch (e) {
  567. } finally {
  568. submitting.value = false;
  569. }
  570. }
  571. </script>
  572. <style scoped lang="scss">
  573. .performance-edit-page {
  574. display: flex;
  575. flex-direction: column;
  576. min-height: 100vh;
  577. background: #f5f7fa;
  578. }
  579. .page-header {
  580. display: flex;
  581. align-items: center;
  582. justify-content: space-between;
  583. height: 56px;
  584. padding: 0 24px;
  585. background: #ffffff;
  586. border-bottom: 1px solid #ebeef5;
  587. .header-left {
  588. display: flex;
  589. gap: 8px;
  590. align-items: center;
  591. font-size: 14px;
  592. color: #606266;
  593. cursor: pointer;
  594. .back-icon {
  595. font-size: 18px;
  596. }
  597. }
  598. .page-title {
  599. position: absolute;
  600. left: 50%;
  601. margin: 0;
  602. font-size: 18px;
  603. font-weight: 600;
  604. color: #303133;
  605. transform: translateX(-50%);
  606. }
  607. .header-right {
  608. color: #606266;
  609. cursor: pointer;
  610. .close-icon {
  611. font-size: 20px;
  612. }
  613. }
  614. }
  615. .page-content {
  616. flex: 1;
  617. padding: 24px;
  618. overflow: auto;
  619. }
  620. .performance-form {
  621. padding: 24px;
  622. background: #ffffff;
  623. border-radius: 8px;
  624. :deep(.el-form-item__label) {
  625. font-size: 14px;
  626. color: #606266;
  627. }
  628. .form-input {
  629. max-width: 360px;
  630. }
  631. .form-textarea {
  632. width: 100%;
  633. max-width: 100%;
  634. }
  635. }
  636. .upload-wrap {
  637. display: flex;
  638. gap: 8px;
  639. align-items: center;
  640. .poster-upload,
  641. .detail-upload {
  642. :deep(.el-upload-list--picture-card) {
  643. --el-upload-list-picture-card-size: 100px;
  644. }
  645. :deep(.el-upload--picture-card) {
  646. width: 100px;
  647. height: 100px;
  648. }
  649. }
  650. .upload-tip {
  651. font-size: 12px;
  652. color: #909399;
  653. }
  654. }
  655. .form-tip {
  656. margin-top: 4px;
  657. font-size: 12px;
  658. color: #909399;
  659. }
  660. .date-time-row {
  661. display: flex;
  662. flex-wrap: wrap;
  663. gap: 8px;
  664. align-items: center;
  665. .sep {
  666. color: #909399;
  667. }
  668. }
  669. .guest-list {
  670. margin-top: 8px;
  671. .guest-item {
  672. display: flex;
  673. gap: 8px;
  674. align-items: center;
  675. padding: 6px 0;
  676. .guest-name {
  677. flex: 1;
  678. font-size: 14px;
  679. }
  680. .guest-remove {
  681. color: #909399;
  682. cursor: pointer;
  683. &:hover {
  684. color: #f56c6c;
  685. }
  686. }
  687. }
  688. }
  689. .view-only-value {
  690. font-size: 14px;
  691. color: #606266;
  692. }
  693. .reject-reason-text {
  694. min-height: 60px;
  695. padding: 8px 0;
  696. word-break: break-word;
  697. white-space: pre-wrap;
  698. }
  699. .audit-status {
  700. font-weight: 500;
  701. &.audit-status--0 {
  702. color: #e6a23c;
  703. }
  704. &.audit-status--1 {
  705. color: #67c23a;
  706. }
  707. &.audit-status--2 {
  708. color: #f56c6c;
  709. }
  710. }
  711. .page-footer {
  712. display: flex;
  713. align-items: center;
  714. justify-content: center;
  715. height: 64px;
  716. background: #ffffff;
  717. border-top: 1px solid #ebeef5;
  718. }
  719. .footer-inner {
  720. display: flex;
  721. gap: 12px;
  722. align-items: center;
  723. justify-content: center;
  724. width: 100%;
  725. max-width: 1100px;
  726. padding: 0 24px;
  727. }
  728. </style>