hookehuyr

✨ feat(修改方言类型组件): 新增模块

1 +/*
2 + * @Date: 2022-06-20 12:56:47
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2022-06-20 15:41:41
5 + * @FilePath: /tswj/src/api/B/localism.js
6 + * @Description: 文件描述
7 + */
8 +import { fn, fetch } from '@/api/fn';
9 +
10 +const Api = {
11 + LOCALISM_LIST_MODI: '/srv/?a=localism_list4modi',
12 + ADD_LOCALISM: '/srv/?a=add_localism',
13 + MODIFY_PROD_LOCALISM: '/srv/?a=modify_prod_localism',
14 +}
15 +
16 +/**
17 + * @description 幼儿园方言列表
18 + * @returns {*} data
19 + */
20 +export const localismListModiAPI = (params) => fn(fetch.get(Api.LOCALISM_LIST_MODI, params));
21 +
22 +/**
23 + * @description 新增方言
24 + * @param {string} localism_name
25 + * @returns {*} data
26 + */
27 +export const addLocalismAPI = (params) => fn(fetch.post(Api.ADD_LOCALISM, params));
28 +
29 +/**
30 + * @description 更新作品方言
31 + * @param {string} prod_id
32 + * @param {string} localism_name
33 + * @returns {*} data
34 + */
35 +export const modifyProdLocalismAPI = (params) => fn(fetch.post(Api.MODIFY_PROD_LOCALISM, params));
1 +<!--
2 + * @Date: 2022-06-20 11:35:50
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2022-06-20 16:51:47
5 + * @FilePath: /tswj/src/components/LocalismBox/index.vue
6 + * @Description: 调整作品方言弹框组件
7 +-->
8 +<template>
9 + <van-overlay :show="show" z-index="1000">
10 + <div class="wrapper" @click.stop>
11 + <div class="block">
12 + <div class="close">
13 + <van-icon name="close" color="#FFFFFF" @click="handleClose" />
14 + </div>
15 + <div class="localism-title">{{ title }}</div>
16 + <div id="localism-list" class="localism-list">
17 + <div v-for="(item, index) in localismList" :id="item.id" :key="index"
18 + :class="[item.checked ? 'checked' : 'unchecked', 'van-hairline--top-bottom', 'localism-item']"
19 + @click="setLocalism(item.id)">
20 + {{ item.localism }}
21 + </div>
22 + <div v-show="show_localism" id="localism-bottom" class="van-hairline--top-bottom localism-item">
23 + <input v-model="localism_name" placeholder="请输入新增的方言名称" style="border: 0; text-align: center;"
24 + @blur="onBlur">
25 + </div>
26 + </div>
27 + <div class="bar">
28 + <div class="button">
29 + <my-button type="plain" @on-click="addLocalism">新增方言</my-button>
30 + </div>
31 + <div class="button">
32 + <my-button type="primary" @on-click="handleSubmit">确定</my-button>
33 + </div>
34 + </div>
35 + </div>
36 + </div>
37 + </van-overlay>
38 +</template>
39 +
40 +<script setup>
41 +import { ref, watch, nextTick } from 'vue'
42 +import MyButton from '@/components/MyButton/index.vue'
43 +import { localismListModiAPI, addLocalismAPI, modifyProdLocalismAPI } from '@/api/B/localism'
44 +import { Toast, Dialog, _ } from '@/utils/generatePackage.js'
45 +
46 +const props = defineProps({
47 + showLocalism: Boolean,
48 + id: Number,
49 + localism: String,
50 + title: String,
51 + type: String, // 值为pass说明是从通过按钮点击进入
52 +})
53 +const emit = defineEmits(['on-close', 'on-submit']);
54 +/**
55 + * 滚动到指定位置
56 + * @param {*} id
57 + */
58 +const scrollToDom = (id) => {
59 + nextTick(() => {
60 + document.getElementById(id)?.scrollIntoView({ block: 'center' });
61 + })
62 +}
63 +
64 +// 处理语言列表数据
65 +let localismList = ref([]);
66 +const raw_id = ref('')
67 +const getLocalismList = async () => {
68 + const { data } = await localismListModiAPI();
69 + localismList.value = data.map((item) => ({ id: item, localism: item, checked: false }))
70 + localismList.value.forEach((item) => {
71 + if (item.localism === props.localism) {
72 + item.checked = true;
73 + raw_id.value = item.id
74 + }
75 + });
76 + scrollToDom(props.localism);
77 +}
78 +
79 +let show = ref(false);
80 +watch(() => props.showLocalism, (v) => {
81 + show.value = v;
82 + if (v) {
83 + getLocalismList()
84 + }
85 +})
86 +
87 +// 点击行选择方言
88 +const setLocalism = (v) => {
89 + localismList.value.forEach((item) => {
90 + item.checked = false;
91 + });
92 + localismList.value.forEach((item) => {
93 + if (item.id === v) {
94 + item.checked = true;
95 + }
96 + });
97 +}
98 +
99 +// 新增方言
100 +const show_localism = ref(false)
101 +const localism_name = ref('')
102 +
103 +const addLocalism = () => { // 滚动到底部,显示新增输入框
104 + show_localism.value = true;
105 + const id = localismList.value[localismList.value.length - 1]['id'];
106 + scrollToDom(id);
107 +}
108 +
109 +const onBlur = () => { // 失焦保存录入方言
110 + if (!localism_name.value) return false;
111 + Dialog.confirm({
112 + title: '温馨提示',
113 + message: `是否确认新增${localism_name.value}?`,
114 + confirmButtonColor: '#11D2B1'
115 + })
116 + .then(async () => {
117 + const { code } = await addLocalismAPI({ localism_name: localism_name.value });
118 + if (code) {
119 + Toast.success('新增成功!');
120 + localismList.value.forEach((item) => {
121 + item.checked = false;
122 + });
123 + localismList.value.push({ id: localism_name.value, localism: localism_name.value, checked: true });
124 + scrollToDom(localism_name.value);
125 + localism_name.value = '';
126 + }
127 + })
128 + .catch(() => {
129 + // on cancel
130 + });
131 +}
132 +
133 +const clearAll = () => {
134 + show.value = false
135 + show_localism.value = false
136 + localismList.value = []
137 + localism_name.value = ''
138 +}
139 +
140 +const handleClose = () => { // 关闭提示框回调
141 + clearAll();
142 + emit('on-close', false)
143 +}
144 +
145 +const handleSubmit = () => { // 提交选择方言
146 + const localism = localismList.value.filter((item) => item.checked === true);
147 + // 原始和提交不一致请求接口提交
148 + if (raw_id.value !== localism[0].id) {
149 + Dialog.confirm({
150 + title: '温馨提示',
151 + message: `是否确认设置方言为${localism[0].id}?`,
152 + confirmButtonColor: '#11D2B1'
153 + })
154 + .then(async () => {
155 + const { code } = await modifyProdLocalismAPI({ prod_id: props.id, localism_name: localism[0].id });
156 + if (code) {
157 + Toast.success('更新成功!');
158 + clearAll();
159 + emit('on-submit', localism[0].id);
160 + }
161 + })
162 + .catch(() => {
163 + // on cancel
164 + });
165 + } else {
166 + clearAll();
167 + emit('on-submit', raw_id.value);
168 + }
169 +}
170 +</script>
171 +
172 +<style lang="less" scoped>
173 +.wrapper {
174 + display: flex;
175 + align-items: center;
176 + justify-content: center;
177 + height: 100%;
178 + width: auto;
179 + text-align: center;
180 +}
181 +
182 +.block {
183 + width: 80%;
184 + // height: 25rem;
185 + background-color: #fff;
186 + border-radius: 10px;
187 + padding: 1rem 0;
188 + position: relative;
189 + margin-top: 1rem;
190 + margin-bottom: 5rem;
191 + .close {
192 + position: absolute;
193 + top: -2rem;
194 + right: 1rem;
195 + font-size: 1.5rem;
196 + }
197 +}
198 +.localism-title {
199 + font-size: 1.25rem;
200 +}
201 +.localism-list {
202 + margin-top: 2rem;
203 + max-height: 20rem;
204 + overflow: auto;
205 +}
206 +
207 +.bar {
208 + display: flex;
209 + align-items: center;
210 + box-sizing: content-box;
211 + background-color: white;
212 + padding: 0.7rem;
213 +
214 + .button {
215 + display: flex;
216 + flex-direction: column;
217 + justify-content: center;
218 + flex: 1;
219 + padding: 0 0.5rem;
220 + }
221 +}
222 +
223 +.localism-item {
224 + padding: 1rem;
225 + text-align: center;
226 +}
227 +.checked {
228 + color: #11d2b1;
229 +}
230 +.unchecked {
231 + color: gray;
232 +}
233 +input::-webkit-input-placeholder {
234 + color: #B0B0B0;
235 +}
236 +</style>