feat(css): 添加移动端 iconfont样式并优化内容编辑组件- 在 main.scss 中添加移动端 iconfont 样式
- 为 contenteditable 组件添加失焦事件处理 - 新增 YLPicker 组件,支持年月日时分秒的自定义格式选择
This commit is contained in:
9
components.d.ts
vendored
9
components.d.ts
vendored
@@ -19,11 +19,18 @@ declare module 'vue' {
|
||||
VanCheckbox: typeof import('vant/es')['Checkbox']
|
||||
VanCheckboxGroup: typeof import('vant/es')['CheckboxGroup']
|
||||
VanCol: typeof import('vant/es')['Col']
|
||||
VanDatePicker: typeof import('vant/es')['DatePicker']
|
||||
VanDatetimePicker: typeof import('vant/es')['DatetimePicker']
|
||||
VanDialog: typeof import('vant/es')['Dialog']
|
||||
VanDivider: typeof import('vant/es')['Divider']
|
||||
VanFiel: typeof import('vant/es')['Fiel']
|
||||
VanField: typeof import('vant/es')['Field']
|
||||
VanGrid: typeof import('vant/es')['Grid']
|
||||
VanGridItem: typeof import('vant/es')['GridItem']
|
||||
VanIcon: typeof import('vant/es')['Icon']
|
||||
VanNavBar: typeof import('vant/es')['NavBar']
|
||||
VanPicker: typeof import('vant/es')['Picker']
|
||||
VanPikcer: typeof import('vant/es')['Pikcer']
|
||||
VanPopup: typeof import('vant/es')['Popup']
|
||||
VanRadio: typeof import('vant/es')['Radio']
|
||||
VanRadioGroup: typeof import('vant/es')['RadioGroup']
|
||||
@@ -33,6 +40,8 @@ declare module 'vue' {
|
||||
VanSwitch: typeof import('vant/es')['Switch']
|
||||
VanTabbar: typeof import('vant/es')['Tabbar']
|
||||
VanTabbarItem: typeof import('vant/es')['TabbarItem']
|
||||
VanTimePicker: typeof import('vant/es')['TimePicker']
|
||||
YLPicker: typeof import('./src/components/YLPicker.vue')['default']
|
||||
YLSelect: typeof import('./src/components/YLSelect.vue')['default']
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@import 'base';
|
||||
@import '../../fonts/iconfont.css';
|
||||
@import 'vant';
|
||||
@import '../../fonts/moblie/iconfont.css';
|
||||
|
||||
a,
|
||||
.green {
|
||||
|
||||
698
src/components/YLPicker.vue
Normal file
698
src/components/YLPicker.vue
Normal file
@@ -0,0 +1,698 @@
|
||||
<!-- vant的picker组件只支持年月日,有些情况下需要一个能支持选择年月日时分秒的picker组件 -->
|
||||
<!-- 本组件可支持“年月日时分秒”任意格式(dateFormat) -->
|
||||
<template>
|
||||
<!-- 弹出层 -->
|
||||
<van-picker
|
||||
ref="dateTimePicker"
|
||||
v-model="data.selectedValues"
|
||||
:title="title"
|
||||
:columns="data.columns"
|
||||
swipe-duration="500"
|
||||
@cancel="cancelOn"
|
||||
@confirm="onConfirm"
|
||||
@change="onChange"
|
||||
/>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, watch, computed } from 'vue';
|
||||
|
||||
// 所有可能用到的日期格式
|
||||
type dateFormat =
|
||||
| 'YYYY'
|
||||
| 'YYYY-MM'
|
||||
| 'YYYY-MM-DD'
|
||||
| 'YYYY-MM-DD HH'
|
||||
| 'YYYY-MM-DD HH:mm'
|
||||
| 'YYYY-MM-DD HH:mm:ss';
|
||||
/** 声明props类型 */
|
||||
interface Props {
|
||||
// 传入的显示隐藏状态
|
||||
showPicker: boolean;
|
||||
// picker标题
|
||||
title?: string;
|
||||
// 传入的日期值
|
||||
values: string;
|
||||
// 自定义格式
|
||||
format?: dateFormat;
|
||||
// 自定义单位
|
||||
units?: string[];
|
||||
// 最小日期时间
|
||||
minDate?: string;
|
||||
// 最大日期时间
|
||||
maxDate?: string;
|
||||
}
|
||||
|
||||
interface IntColumnsItem {
|
||||
text: string;
|
||||
value: string;
|
||||
children?: IntColumnsItem[];
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
showPicker: false,
|
||||
title: '请选择日期',
|
||||
values: '',
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
units: () => [],
|
||||
minDate: '',
|
||||
maxDate: ''
|
||||
});
|
||||
|
||||
// 定义要向父组件传递的事件
|
||||
const emit = defineEmits(['cancel', 'confirm']);
|
||||
|
||||
const dateTimePicker = ref(null);
|
||||
|
||||
// 定义数据
|
||||
const data = reactive<{
|
||||
isPicker: boolean;
|
||||
columns: IntColumnsItem[];
|
||||
selectedValues: any[];
|
||||
tempSelectedValues: any[];
|
||||
}>({
|
||||
// 是否显示弹出层
|
||||
isPicker: false,
|
||||
// 所有时间列
|
||||
columns: [],
|
||||
// 控件选择的时间值
|
||||
selectedValues: [],
|
||||
// 临时数据,数据变化过程中选中的值
|
||||
tempSelectedValues: []
|
||||
});
|
||||
// 获取数据类型
|
||||
const getType = (v: any) => {
|
||||
return Object.prototype.toString.call(v).slice(8, -1).toLowerCase();
|
||||
};
|
||||
// 返回指定格式的日期时间
|
||||
const getDateByFormat = (date: Date | string, fmt: dateFormat) => {
|
||||
const thisDateType = getType(date);
|
||||
if (date === '' || (thisDateType !== 'date' && thisDateType !== 'string')) {
|
||||
date = new Date();
|
||||
} else if (thisDateType === 'string') {
|
||||
date = new Date((date as string).replace(/-/g, '/'));
|
||||
} else {
|
||||
date = new Date(date);
|
||||
}
|
||||
const Y = date.getFullYear();
|
||||
const M = date.getMonth() + 1;
|
||||
const D = date.getDate();
|
||||
const h = date.getHours();
|
||||
const m = date.getMinutes();
|
||||
const s = date.getSeconds();
|
||||
// 个位数补0
|
||||
// 月份比实际获取的少1,所以要加1
|
||||
const _M = M < 10 ? `0${M}` : M.toString();
|
||||
const _D = D < 10 ? `0${D}` : D.toString();
|
||||
const _h = h < 10 ? `0${h}` : h.toString();
|
||||
const _m = m < 10 ? `0${m}` : m.toString();
|
||||
const _s = s < 10 ? `0${s}` : s.toString();
|
||||
return fmt
|
||||
.replace(/YYYY/g, Y.toString())
|
||||
.replace('MM', _M)
|
||||
.replace('DD', _D)
|
||||
.replace('HH', _h)
|
||||
.replace('mm', _m)
|
||||
.replace('ss', _s);
|
||||
};
|
||||
|
||||
// 比较两个日期大小
|
||||
const dateRangeLegal = (sDate: string | Date, eDate: string | Date) => {
|
||||
if (!sDate || !eDate) {
|
||||
return false;
|
||||
}
|
||||
// 补全模板
|
||||
const complateStr = '0000-01-01 00:00:00';
|
||||
// 兼容ios
|
||||
if (typeof sDate === 'string') {
|
||||
sDate = (sDate + complateStr.slice(sDate.length)).replace(/-/g, '/');
|
||||
}
|
||||
if (typeof eDate === 'string') {
|
||||
eDate = (eDate + complateStr.slice(eDate.length)).replace(/-/g, '/');
|
||||
}
|
||||
return new Date(sDate) <= new Date(eDate);
|
||||
};
|
||||
|
||||
/**
|
||||
* 空闲位自动补全0
|
||||
* @param num 数据
|
||||
* @param len 设定长度
|
||||
*/
|
||||
const autoFillZero = (num: number, len: number) => {
|
||||
return (Array(len).join('0') + num).slice(-len);
|
||||
};
|
||||
|
||||
// 获取某年某月有多少天
|
||||
const getCountDays = (year: number, month: number) => {
|
||||
// 获取某年某月多少天
|
||||
const day = new Date(year, month, 0);
|
||||
return day.getDate();
|
||||
};
|
||||
|
||||
// 获取最小时间范围
|
||||
const getMinDateLimit = computed(() => {
|
||||
return getDateByFormat(
|
||||
props.minDate && props.minDate.length >= 0
|
||||
? props.minDate
|
||||
: `${new Date().getFullYear() - 10}-01-01 00:00:00`,
|
||||
props.format
|
||||
);
|
||||
});
|
||||
|
||||
// 获取最大时间范围
|
||||
const getMaxDateLimit = computed(() => {
|
||||
const thisMax = getDateByFormat(
|
||||
props.maxDate && props.maxDate.length >= 0
|
||||
? props.maxDate
|
||||
: `${new Date().getFullYear() + 10}-12-31 23:59:59`,
|
||||
props.format
|
||||
);
|
||||
const tempStr = '0000-12-31 23:59:59';
|
||||
const result =
|
||||
props.maxDate.length !== 0 && thisMax.length > props.maxDate.length
|
||||
? thisMax.slice(0, props.maxDate.length) + tempStr.slice(props.maxDate.length)
|
||||
: thisMax;
|
||||
return result.slice(0, props.format.length);
|
||||
});
|
||||
|
||||
function onChange({
|
||||
selectedValues,
|
||||
columnIndex
|
||||
}: {
|
||||
// 所有列选中值
|
||||
selectedValues: any[];
|
||||
// 当前变化列索引
|
||||
columnIndex: number;
|
||||
}) {
|
||||
// 更新渲染变化的列之后的所有列(columnIndex)
|
||||
const splitArr = ['-', '-', ' ', ':', ':'];
|
||||
let iiindex = -1;
|
||||
const changeValue = selectedValues.reduce((a, b) => {
|
||||
iiindex += 1;
|
||||
return a + splitArr[iiindex] + b;
|
||||
});
|
||||
// 当前列变化后此时此刻时间
|
||||
// 更新当前列之后的所有列(包括当前列)
|
||||
const updateColumns: function[] = [
|
||||
renderYearColumns,
|
||||
renderMonthColumns,
|
||||
renderDayColumns,
|
||||
renderHourColumns,
|
||||
renderMinuteColumns,
|
||||
renderSecondColumns
|
||||
];
|
||||
updateColumns[columnIndex] &&
|
||||
updateColumns[columnIndex](changeValue, getMinDateLimit.value, getMaxDateLimit.value, false);
|
||||
}
|
||||
|
||||
// 渲染全部列
|
||||
const getcolumns = () => {
|
||||
// 先清空全部列
|
||||
data.columns = [];
|
||||
// 清空年月日时分秒时间值
|
||||
data.tempSelectedValues = [];
|
||||
data.selectedValues = [];
|
||||
// 获取props.values转换成指定格式后的日期时间
|
||||
const defaultDateTime = getDateByFormat(props.values, props.format);
|
||||
let usefullDateTime = defaultDateTime;
|
||||
if (!dateRangeLegal(getMinDateLimit.value, defaultDateTime)) {
|
||||
usefullDateTime = getMinDateLimit.value;
|
||||
} else if (!dateRangeLegal(defaultDateTime, getMaxDateLimit.value)) {
|
||||
usefullDateTime = getMaxDateLimit.value;
|
||||
}
|
||||
// 渲染修正“年”列
|
||||
renderYearColumns(usefullDateTime, getMinDateLimit.value, getMaxDateLimit.value, true);
|
||||
};
|
||||
/**
|
||||
* 渲染年所在列,并自动修正在“年”这一列列范围之外的数据
|
||||
* @param v 需要做比较的数据,dateFormat格式
|
||||
* @param s 比较条件,开始时间临界值,dateFormat格式
|
||||
* @param e 比较条件,结束时间临界值,dateFormat格式
|
||||
* @param isFirst 是否是第一次渲染,需要定位到当前
|
||||
* @param outRange 是否超出范围之外
|
||||
*/
|
||||
const renderYearColumns = (v: string, s: string, e: string, isFirst: boolean) => {
|
||||
// 设置年范围
|
||||
// 获取前后十年数组
|
||||
const listArr: any = [];
|
||||
const Currentday = new Date().getFullYear();
|
||||
// 最小月份
|
||||
let forStart = 2020;
|
||||
// 最小月份
|
||||
let forEnd = 2040;
|
||||
if (s && e) {
|
||||
const startYearLimit = s.slice(0, 4);
|
||||
const endYearLimit = e.slice(0, 4);
|
||||
// 如果最小、最大日期设定的范围错误
|
||||
if (!dateRangeLegal(s, e)) {
|
||||
forStart = Currentday - 10;
|
||||
forEnd = Currentday + 10;
|
||||
} else {
|
||||
if (startYearLimit === endYearLimit) {
|
||||
forStart = Number(startYearLimit);
|
||||
forEnd = Number(startYearLimit);
|
||||
} else {
|
||||
forStart = Number(startYearLimit);
|
||||
forEnd = Number(endYearLimit);
|
||||
}
|
||||
}
|
||||
} else if (s) {
|
||||
const startYearLimit = s.slice(0, 4);
|
||||
if (Currentday <= Number(startYearLimit)) {
|
||||
forStart = Number(startYearLimit);
|
||||
forEnd = Number(startYearLimit) + 10;
|
||||
} else {
|
||||
forStart = Number(startYearLimit);
|
||||
forEnd = Currentday + 10;
|
||||
}
|
||||
} else if (e) {
|
||||
const endYearLimit = e.slice(0, 4);
|
||||
if (Currentday <= Number(endYearLimit)) {
|
||||
forStart = Currentday - 10;
|
||||
forEnd = Number(endYearLimit);
|
||||
} else {
|
||||
forStart = Number(endYearLimit) - 10;
|
||||
forEnd = Number(endYearLimit);
|
||||
}
|
||||
} else {
|
||||
forStart = Currentday - 10;
|
||||
forEnd = Currentday + 10;
|
||||
}
|
||||
for (let m = forStart; m <= forEnd; m++) {
|
||||
listArr.push({
|
||||
text: `${m}${props.units[0] || ''}`,
|
||||
value: m.toString()
|
||||
});
|
||||
}
|
||||
|
||||
// 判断当前“年”是否在以上合理范围之内
|
||||
const thisYear = Number(v.slice(0, 4));
|
||||
// 当前定位到的年份
|
||||
let vmValue: string | number = '';
|
||||
if (thisYear < forStart) {
|
||||
vmValue = forStart;
|
||||
} else if (thisYear > forEnd) {
|
||||
vmValue = forEnd;
|
||||
} else {
|
||||
// 范围正确
|
||||
vmValue = thisYear;
|
||||
}
|
||||
// 插入/更新到data中
|
||||
if (isFirst) {
|
||||
data.columns.push(listArr);
|
||||
data.tempSelectedValues.push(autoFillZero(vmValue, 4));
|
||||
} else {
|
||||
data.columns[0] = listArr;
|
||||
data.tempSelectedValues[0] = autoFillZero(vmValue, 4);
|
||||
}
|
||||
|
||||
if (props.format.length >= 7) {
|
||||
// 至少是“YYYY-MM”格式,则渲染“月”
|
||||
// 根据当前年渲染“月”这一列
|
||||
renderMonthColumns(autoFillZero(vmValue, 4) + v.slice(4), s, e, isFirst);
|
||||
} else {
|
||||
// 确定选择结果
|
||||
data.selectedValues = [...data.tempSelectedValues];
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 渲染月所在列,并自动修正在“月”这一列列范围之外的数据
|
||||
* @param v 需要做比较的数据,dateFormat格式
|
||||
* @param s 比较条件,开始时间临界值,dateFormat格式
|
||||
* @param e 比较条件,结束时间临界值,dateFormat格式
|
||||
* @param isFirst 是否是第一次渲染,需要定位到当前
|
||||
* @param outRange 是否超出范围之外
|
||||
*/
|
||||
const renderMonthColumns = (
|
||||
v: string,
|
||||
s: string,
|
||||
e: string,
|
||||
isFirst: boolean,
|
||||
outRange: boolean = false
|
||||
) => {
|
||||
const thisY = Number(v.slice(0, 4)); // 获取当前月
|
||||
const thisM = Number(v.slice(5, 7)); // 获取当前月
|
||||
const minY = Number(s.slice(0, 4)); // 最小年份
|
||||
const maxY = Number(e.slice(0, 4)); // 最大年份
|
||||
const listArr: any = []; // 获取月份数组
|
||||
let forStart = -1; // 最小月份
|
||||
let forEnd = -1; // 最小月份
|
||||
if (thisY === minY && thisY === maxY) {
|
||||
forStart = Number(s.slice(5, 7));
|
||||
forEnd = Number(e.slice(5, 7));
|
||||
} else if (thisY === minY) {
|
||||
forStart = Number(s.slice(5, 7));
|
||||
forEnd = 12;
|
||||
} else if (thisY === maxY) {
|
||||
forStart = 1;
|
||||
forEnd = Number(e.slice(5, 7));
|
||||
} else {
|
||||
forStart = 1;
|
||||
forEnd = 12;
|
||||
}
|
||||
for (let m = forStart; m <= forEnd; m++) {
|
||||
listArr.push({
|
||||
text: autoFillZero(m, 2) + (props.units[1] || ''),
|
||||
value: autoFillZero(m, 2)
|
||||
});
|
||||
}
|
||||
// 判断当前月是否在此范围之内
|
||||
let vmValue: string | number = '';
|
||||
if (thisM < forStart || outRange) {
|
||||
vmValue = forStart;
|
||||
outRange = true;
|
||||
} else if (thisM > forEnd) {
|
||||
vmValue = forEnd;
|
||||
outRange = true;
|
||||
} else {
|
||||
// 范围正确
|
||||
vmValue = thisM;
|
||||
}
|
||||
// 插入/更新到data中
|
||||
if (isFirst) {
|
||||
data.columns.push(listArr);
|
||||
data.tempSelectedValues.push(autoFillZero(vmValue, 2));
|
||||
} else {
|
||||
data.columns[1] = listArr;
|
||||
data.tempSelectedValues[1] = autoFillZero(vmValue, 2);
|
||||
}
|
||||
|
||||
if (props.format.length >= 10) {
|
||||
// 至少是“YYYY-MM-DD”格式,则渲染“日”
|
||||
// 根据当前年渲染“日”这一列
|
||||
renderDayColumns(v.slice(0, 5) + autoFillZero(vmValue, 2) + v.slice(7), s, e, isFirst);
|
||||
} else {
|
||||
// 确定选择结果
|
||||
data.selectedValues = [...data.tempSelectedValues];
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 渲染日所在列,并自动修正在“日”这一列列范围之外的数据
|
||||
* @param v 需要做比较的数据,dateFormat格式
|
||||
* @param s 比较条件,开始时间临界值,dateFormat格式
|
||||
* @param e 比较条件,结束时间临界值,dateFormat格式
|
||||
* @param isFirst 是否是第一次渲染,需要定位到当前
|
||||
* @param outRange 是否超出范围之外
|
||||
*/
|
||||
const renderDayColumns = (
|
||||
v: string,
|
||||
s: string,
|
||||
e: string,
|
||||
isFirst: boolean,
|
||||
outRange: boolean = false
|
||||
) => {
|
||||
const thisYM = v.slice(0, 7); // 获取当前年月
|
||||
const thisD = Number(v.slice(8, 10)); // 获取当前日
|
||||
const startYM = s.slice(0, 7); // 开始时间临界值
|
||||
const endYM = e.slice(0, 7); // 结束时间临界值
|
||||
const listArr: any = []; // 获取月份数组
|
||||
let forStart = -1; // 最小月份
|
||||
let forEnd = -1; // 最小月份
|
||||
if (thisYM === startYM && thisYM === endYM) {
|
||||
forStart = Number(s.slice(8, 10)); // 开始时间的天临界值
|
||||
forEnd = Number(e.slice(8, 10)); // 结束时间的天临界值
|
||||
} else if (thisYM === startYM) {
|
||||
forStart = Number(s.slice(8, 10));
|
||||
forEnd = getCountDays(Number(v.slice(0, 4)), Number(v.slice(5, 7)));
|
||||
} else if (thisYM === endYM) {
|
||||
forStart = 1;
|
||||
forEnd = Number(e.slice(8, 10)); // 结束时间的天临界值
|
||||
} else {
|
||||
forStart = 1;
|
||||
forEnd = getCountDays(Number(v.slice(0, 4)), Number(v.slice(5, 7)));
|
||||
}
|
||||
for (let m = forStart; m <= forEnd; m++) {
|
||||
listArr.push({
|
||||
text: autoFillZero(m, 2) + (props.units[2] || ''),
|
||||
value: autoFillZero(m, 2)
|
||||
});
|
||||
}
|
||||
// 判断当前日是否在此范围之内
|
||||
let vmValue: string | number = '';
|
||||
if (thisD < forStart || outRange) {
|
||||
vmValue = forStart;
|
||||
outRange = true;
|
||||
} else if (thisD > forEnd) {
|
||||
vmValue = forEnd;
|
||||
outRange = true;
|
||||
} else {
|
||||
// 范围正确
|
||||
vmValue = thisD;
|
||||
}
|
||||
// 插入/更新到data中
|
||||
if (isFirst) {
|
||||
data.columns.push(listArr);
|
||||
data.tempSelectedValues.push(autoFillZero(vmValue, 2));
|
||||
} else {
|
||||
data.columns[2] = listArr;
|
||||
data.tempSelectedValues[2] = autoFillZero(vmValue, 2);
|
||||
}
|
||||
|
||||
if (props.format.length >= 13) {
|
||||
// 至少是“YYYY-MM-DD HH”格式,则渲染“时”
|
||||
// 根据当前年渲染“日”这一列
|
||||
renderHourColumns(v.slice(0, 8) + autoFillZero(vmValue, 2) + v.slice(10), s, e, isFirst);
|
||||
} else {
|
||||
// 确定选择结果
|
||||
data.selectedValues = [...data.tempSelectedValues];
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 渲染小时所在列,并自动修正在“时”这一列列范围之外的数据
|
||||
* @param v 需要做比较的数据,dateFormat格式
|
||||
* @param s 比较条件,开始时间临界值,dateFormat格式
|
||||
* @param e 比较条件,结束时间临界值,dateFormat格式
|
||||
* @param isFirst 是否是第一次渲染,需要定位到当前
|
||||
* @param outRange 是否超出范围之外
|
||||
*/
|
||||
const renderHourColumns = (
|
||||
v: string,
|
||||
s: string,
|
||||
e: string,
|
||||
isFirst: boolean,
|
||||
outRange: boolean = false
|
||||
) => {
|
||||
const thisYMD = v.slice(0, 10); // 获取当前年月日
|
||||
const startYMD = s.slice(0, 10); // 开始时间临界值
|
||||
const endYMD = e.slice(0, 10); // 结束时间临界值
|
||||
const thisH = Number(v.slice(11, 13)); // 获取当前小时
|
||||
const listArr: any = []; // 获取小时数组
|
||||
let forStart = -1; // 最小月份
|
||||
let forEnd = -1; // 最小月份
|
||||
if (thisYMD === startYMD && thisYMD === endYMD) {
|
||||
forStart = Number(s.slice(11, 13)); // 开始时间的小时临界值
|
||||
forEnd = Number(e.slice(11, 13)); // 结束时间的小时临界值
|
||||
} else if (thisYMD === startYMD) {
|
||||
forStart = Number(s.slice(11, 13));
|
||||
forEnd = 23;
|
||||
} else if (thisYMD === endYMD) {
|
||||
forStart = 0;
|
||||
forEnd = Number(e.slice(11, 13));
|
||||
} else {
|
||||
forStart = 0;
|
||||
forEnd = 23;
|
||||
}
|
||||
for (let m = forStart; m <= forEnd; m++) {
|
||||
listArr.push({
|
||||
text: autoFillZero(m, 2) + (props.units[3] || ''),
|
||||
value: autoFillZero(m, 2)
|
||||
});
|
||||
}
|
||||
// 判断当前小时是否在此范围之内
|
||||
let vmValue: string | number = '';
|
||||
if (thisH < forStart || outRange) {
|
||||
vmValue = forStart;
|
||||
outRange = true;
|
||||
} else if (thisH > forEnd) {
|
||||
vmValue = forEnd;
|
||||
outRange = true;
|
||||
} else {
|
||||
// 范围正确
|
||||
vmValue = thisH;
|
||||
}
|
||||
// 插入/更新到data中
|
||||
if (isFirst) {
|
||||
data.columns.push(listArr);
|
||||
data.tempSelectedValues.push(autoFillZero(vmValue, 2));
|
||||
} else {
|
||||
data.columns[3] = listArr;
|
||||
data.tempSelectedValues[3] = autoFillZero(vmValue, 2);
|
||||
}
|
||||
|
||||
if (props.format.length >= 16) {
|
||||
// 至少是“YYYY-MM-DD HH:mm”格式,则渲染“分”
|
||||
// 根据当前年渲染“分”这一列
|
||||
renderMinuteColumns(v.slice(0, 11) + autoFillZero(vmValue, 2) + v.slice(13), s, e, isFirst);
|
||||
} else {
|
||||
// 确定选择结果
|
||||
data.selectedValues = [...data.tempSelectedValues];
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 渲染分钟所在列,并自动修正在“分”这一列列范围之外的数据
|
||||
* @param v 需要做比较的数据,dateFormat格式
|
||||
* @param s 比较条件,开始时间临界值,dateFormat格式
|
||||
* @param e 比较条件,结束时间临界值,dateFormat格式
|
||||
* @param isFirst 是否是第一次渲染,需要定位到当前
|
||||
* @param outRange 是否超出范围之外
|
||||
*/
|
||||
const renderMinuteColumns = (
|
||||
v: string,
|
||||
s: string,
|
||||
e: string,
|
||||
isFirst: boolean,
|
||||
outRange: boolean = false
|
||||
) => {
|
||||
const thisYMDH = v.slice(0, 13); // 获取当前年月日小时
|
||||
const startYMDH = s.slice(0, 13); // 开始时间临界值
|
||||
const endYMDH = e.slice(0, 13); // 结束时间临界值
|
||||
const thisM = Number(v.slice(14, 16)); // 获取当前分钟
|
||||
const listArr: any = []; // 获取数组
|
||||
let forStart = -1; // 循环最小值
|
||||
let forEnd = -1; // 循环最大值
|
||||
if (thisYMDH === startYMDH && thisYMDH === endYMDH) {
|
||||
forStart = Number(s.slice(14, 16));
|
||||
forEnd = Number(e.slice(14, 16));
|
||||
} else if (thisYMDH === startYMDH) {
|
||||
forStart = Number(s.slice(14, 16));
|
||||
forEnd = 59;
|
||||
} else if (thisYMDH === endYMDH) {
|
||||
forStart = 0;
|
||||
forEnd = Number(e.slice(14, 16));
|
||||
} else {
|
||||
forStart = 0;
|
||||
forEnd = 59;
|
||||
}
|
||||
for (let m = forStart; m <= forEnd; m++) {
|
||||
listArr.push({
|
||||
text: autoFillZero(m, 2) + (props.units[4] || ''),
|
||||
value: autoFillZero(m, 2)
|
||||
});
|
||||
}
|
||||
// 判断当前小时是否在此范围之内
|
||||
let vmValue: string | number = '';
|
||||
if (thisM < forStart || outRange) {
|
||||
vmValue = forStart;
|
||||
outRange = true;
|
||||
} else if (thisM > forEnd) {
|
||||
vmValue = forEnd;
|
||||
outRange = true;
|
||||
} else {
|
||||
// 范围正确
|
||||
vmValue = thisM;
|
||||
}
|
||||
// 插入/更新到data中
|
||||
if (isFirst) {
|
||||
data.columns.push(listArr);
|
||||
data.tempSelectedValues.push(autoFillZero(vmValue, 2));
|
||||
} else {
|
||||
data.columns[4] = listArr;
|
||||
data.tempSelectedValues[4] = autoFillZero(vmValue, 2);
|
||||
}
|
||||
|
||||
if (props.format.length === 19) {
|
||||
// 至少是“YYYY-MM-DD HH:mm:ss”格式,则渲染“秒”
|
||||
// 根据当前年渲染“秒”这一列
|
||||
renderSecondColumns(v.slice(0, 14) + autoFillZero(vmValue, 2) + v.slice(16), s, e, isFirst);
|
||||
} else {
|
||||
// 确定选择结果
|
||||
data.selectedValues = [...data.tempSelectedValues];
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 渲染秒钟所在列,并自动修正在“秒”这一列列范围之外的数据
|
||||
* @param v 需要做比较的数据,dateFormat格式
|
||||
* @param s 比较条件,开始时间临界值,dateFormat格式
|
||||
* @param e 比较条件,结束时间临界值,dateFormat格式
|
||||
* @param isFirst 是否是第一次渲染,需要定位到当前
|
||||
* @param outRange 是否超出范围之外
|
||||
*/
|
||||
const renderSecondColumns = (
|
||||
v: string,
|
||||
s: string,
|
||||
e: string,
|
||||
isFirst: boolean,
|
||||
outRange: boolean = false
|
||||
) => {
|
||||
const thisYMDHM = v.slice(0, 16); // 获取当前年月日小时
|
||||
const startYMDHM = s.slice(0, 16); // 开始时间临界值
|
||||
const endYMDHM = e.slice(0, 16); // 结束时间临界值
|
||||
const thisS = Number(v.slice(17, 19)); // 获取当前分钟
|
||||
const listArr: any = []; // 获取数组
|
||||
let forStart = -1; // 循环最小值
|
||||
let forEnd = -1; // 循环最大值
|
||||
if (thisYMDHM === startYMDHM && thisYMDHM === endYMDHM) {
|
||||
forStart = Number(s.slice(17, 19));
|
||||
forEnd = Number(e.slice(17, 19));
|
||||
} else if (thisYMDHM === startYMDHM) {
|
||||
forStart = Number(s.slice(17, 19));
|
||||
forEnd = 59;
|
||||
} else if (thisYMDHM === endYMDHM) {
|
||||
forStart = 0;
|
||||
forEnd = Number(e.slice(17, 19));
|
||||
} else {
|
||||
forStart = 0;
|
||||
forEnd = 59;
|
||||
}
|
||||
for (let m = forStart; m <= forEnd; m++) {
|
||||
listArr.push({
|
||||
text: autoFillZero(m, 2) + (props.units[5] || ''),
|
||||
value: autoFillZero(m, 2)
|
||||
});
|
||||
}
|
||||
// 判断当前小时是否在此范围之内
|
||||
let vmValue: string | number = '';
|
||||
if (thisS < forStart || outRange) {
|
||||
vmValue = forStart;
|
||||
outRange = true;
|
||||
} else if (thisS > forEnd) {
|
||||
vmValue = forEnd;
|
||||
outRange = true;
|
||||
} else {
|
||||
// 范围正确
|
||||
vmValue = thisS;
|
||||
}
|
||||
// 插入/更新到data中
|
||||
if (isFirst) {
|
||||
data.columns.push(listArr);
|
||||
data.tempSelectedValues.push(autoFillZero(vmValue, 2));
|
||||
} else {
|
||||
data.columns[5] = listArr;
|
||||
data.tempSelectedValues[5] = autoFillZero(vmValue, 2);
|
||||
}
|
||||
// 确定选择结果
|
||||
data.selectedValues = [...data.tempSelectedValues];
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.showPicker,
|
||||
(val) => {
|
||||
data.isPicker = val;
|
||||
if (val) {
|
||||
// console.log("当前最大最小值判断结果", getMinDateLimit.value, getMaxDateLimit.value);
|
||||
// 每次显示前重新渲染全部列
|
||||
getcolumns();
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true // 立即监听--进入就会执行一次 监听显影状态
|
||||
}
|
||||
);
|
||||
|
||||
// 时间选择器关闭 值不改变并关闭弹框
|
||||
function cancelOn() {
|
||||
emit('cancel');
|
||||
}
|
||||
|
||||
// 时间选择器确定 值改变
|
||||
function onConfirm() {
|
||||
// 注意:data.selectedValues比selectedValues更准确
|
||||
// 拼接数据
|
||||
const splitArr = ['-', '-', ' ', ':', ':'];
|
||||
let iiindex = -1;
|
||||
const changeValue = data.selectedValues.reduce((a, b) => {
|
||||
iiindex += 1;
|
||||
return a + splitArr[iiindex] + b;
|
||||
});
|
||||
emit('confirm', changeValue);
|
||||
}
|
||||
</script>
|
||||
@@ -86,7 +86,11 @@ onMounted(() => {
|
||||
editor.value.addEventListener('focus', () => {
|
||||
showAction.value = true;
|
||||
});
|
||||
|
||||
editor.value.addEventListener('blur', () => {
|
||||
setTimeout(() => {
|
||||
showAction.value = false;
|
||||
});
|
||||
});
|
||||
document.addEventListener('resize', () => {
|
||||
showAction.value = false;
|
||||
});
|
||||
|
||||
@@ -9,6 +9,14 @@
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont')
|
||||
format('svg');
|
||||
src:
|
||||
url('//at.alicdn.com/t/c/font_4841764_vat2jbvw3q.woff2?t=1741575060989') format('woff2'),
|
||||
url('//at.alicdn.com/t/c/font_4841764_vat2jbvw3q.woff?t=1741575060989') format('woff'),
|
||||
url('//at.alicdn.com/t/c/font_4841764_vat2jbvw3q.ttf?t=1741575060989') format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: '';
|
||||
}
|
||||
|
||||
.logo {
|
||||
|
||||
548
src/fonts/moblie/demo.css
Normal file
548
src/fonts/moblie/demo.css
Normal file
@@ -0,0 +1,548 @@
|
||||
/* Logo 字体 */
|
||||
@font-face {
|
||||
font-family: 'iconfont logo';
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
|
||||
src:
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix')
|
||||
format('embedded-opentype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont')
|
||||
format('svg');
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-style: normal;
|
||||
font-size: 160px;
|
||||
font-family: 'iconfont logo';
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
/* tabs */
|
||||
.nav-tabs {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-more {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 42px;
|
||||
color: #666;
|
||||
line-height: 42px;
|
||||
}
|
||||
|
||||
#tabs {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
#tabs li {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: 100px;
|
||||
height: 40px;
|
||||
margin-bottom: -1px;
|
||||
border-bottom: 2px solid transparent;
|
||||
color: #666;
|
||||
font-size: 16px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#tabs .active {
|
||||
border-bottom-color: #f00;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.tab-container .content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 页面布局 */
|
||||
.main {
|
||||
width: 960px;
|
||||
margin: 0 auto;
|
||||
padding: 30px 100px;
|
||||
}
|
||||
|
||||
.main .logo {
|
||||
overflow: hidden;
|
||||
height: 110px;
|
||||
margin-top: -50px;
|
||||
margin-bottom: 30px;
|
||||
color: #333;
|
||||
line-height: 1;
|
||||
text-align: left;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.main .logo a {
|
||||
color: #333;
|
||||
font-size: 160px;
|
||||
}
|
||||
|
||||
.helps {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.helps pre {
|
||||
overflow: auto;
|
||||
margin: 10px 0;
|
||||
padding: 20px;
|
||||
border: solid 1px #e7e1cd;
|
||||
background-color: #fffdef;
|
||||
}
|
||||
|
||||
.icon_lists {
|
||||
overflow: hidden;
|
||||
width: 100% !important;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.icon_lists li {
|
||||
width: 100px;
|
||||
margin-right: 20px;
|
||||
margin-bottom: 10px;
|
||||
list-style: none !important;
|
||||
text-align: center;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.icon_lists li .code-name {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.icon_lists .icon {
|
||||
display: block;
|
||||
height: 100px;
|
||||
margin: 10px auto;
|
||||
color: #333;
|
||||
font-size: 42px;
|
||||
line-height: 100px;
|
||||
-webkit-transition:
|
||||
font-size 0.25s linear,
|
||||
width 0.25s linear;
|
||||
-moz-transition:
|
||||
font-size 0.25s linear,
|
||||
width 0.25s linear;
|
||||
transition:
|
||||
font-size 0.25s linear,
|
||||
width 0.25s linear;
|
||||
}
|
||||
|
||||
.icon_lists .icon:hover {
|
||||
font-size: 100px;
|
||||
}
|
||||
|
||||
.icon_lists .svg-icon {
|
||||
/* 图标和文字相邻时,垂直对齐 */
|
||||
vertical-align: -0.15em;
|
||||
|
||||
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
|
||||
normalize.css 中也包含这行 */
|
||||
overflow: hidden;
|
||||
|
||||
/* 通过设置 font-size 来改变图标大小 */
|
||||
width: 1em;
|
||||
|
||||
/* 通过设置 color 来改变 SVG 的颜色/fill */
|
||||
fill: currentcolor;
|
||||
}
|
||||
|
||||
.icon_lists li .name,
|
||||
.icon_lists li .code-name {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* markdown 样式 */
|
||||
.markdown {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.markdown img {
|
||||
vertical-align: middle;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
margin-bottom: 24px;
|
||||
color: #404040;
|
||||
font-weight: 500;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.markdown h2,
|
||||
.markdown h3,
|
||||
.markdown h4,
|
||||
.markdown h5,
|
||||
.markdown h6 {
|
||||
clear: both;
|
||||
margin: 1.6em 0 0.6em;
|
||||
color: #404040;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.markdown h4 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.markdown h5 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown h6 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
clear: both;
|
||||
height: 1px;
|
||||
margin: 16px 0;
|
||||
border: 0;
|
||||
background: #e9e9e9;
|
||||
}
|
||||
|
||||
.markdown p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown > p,
|
||||
.markdown > blockquote,
|
||||
.markdown > .highlight,
|
||||
.markdown > ol,
|
||||
.markdown > ul {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.markdown ul > li {
|
||||
list-style: circle;
|
||||
}
|
||||
|
||||
.markdown > ul li,
|
||||
.markdown blockquote ul > li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown > ul li p,
|
||||
.markdown > ol li p {
|
||||
margin: 0.6em 0;
|
||||
}
|
||||
|
||||
.markdown ol > li {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.markdown > ol li,
|
||||
.markdown blockquote ol > li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown code {
|
||||
margin: 0 3px;
|
||||
padding: 0 5px;
|
||||
border-radius: 3px;
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
.markdown strong,
|
||||
.markdown b {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown > table {
|
||||
width: 95%;
|
||||
margin-bottom: 24px;
|
||||
border: 1px solid #e9e9e9;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
empty-cells: show;
|
||||
}
|
||||
|
||||
.markdown > table th {
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.markdown > table th,
|
||||
.markdown > table td {
|
||||
padding: 8px 16px;
|
||||
border: 1px solid #e9e9e9;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.markdown > table th {
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
.markdown blockquote {
|
||||
margin: 1em 0;
|
||||
padding-left: 0.8em;
|
||||
border-left: 4px solid #e9e9e9;
|
||||
color: #999;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.markdown blockquote p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.markdown .anchor {
|
||||
margin-left: 8px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.markdown .waiting {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.markdown h1:hover .anchor,
|
||||
.markdown h2:hover .anchor,
|
||||
.markdown h3:hover .anchor,
|
||||
.markdown h4:hover .anchor,
|
||||
.markdown h5:hover .anchor,
|
||||
.markdown h6:hover .anchor {
|
||||
display: inline-block;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.markdown > br,
|
||||
.markdown > p > br {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: white;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-meta {
|
||||
color: #969896;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-strong,
|
||||
.hljs-emphasis,
|
||||
.hljs-quote {
|
||||
color: #df5000;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-type {
|
||||
color: #a71d5d;
|
||||
}
|
||||
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-attribute {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name {
|
||||
color: #63a35c;
|
||||
}
|
||||
|
||||
.hljs-tag {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-attr,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #795da3;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background-color: #eaffea;
|
||||
color: #55a532;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background-color: #ffecec;
|
||||
color: #bd2c00;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 代码高亮 */
|
||||
|
||||
/* PrismJS 1.15.0
|
||||
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
|
||||
|
||||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
background: none;
|
||||
color: black;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
line-height: 1.5;
|
||||
text-align: left;
|
||||
text-shadow: 0 1px white;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-wrap: normal;
|
||||
word-break: normal;
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre[class*='language-']::-moz-selection,
|
||||
pre[class*='language-'] ::-moz-selection,
|
||||
code[class*='language-']::-moz-selection,
|
||||
code[class*='language-'] ::-moz-selection {
|
||||
background: #b3d4fc;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
pre[class*='language-']::selection,
|
||||
pre[class*='language-'] ::selection,
|
||||
code[class*='language-']::selection,
|
||||
code[class*='language-'] ::selection {
|
||||
background: #b3d4fc;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
@media print {
|
||||
code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*='language-'] {
|
||||
overflow: auto;
|
||||
margin: 0.5em 0;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
background: #f5f2f0;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*='language-'] {
|
||||
padding: 0.1em;
|
||||
border-radius: 0.3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
background: hsla(0deg, 0%, 100%, 0.5);
|
||||
color: #9a6e3a;
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
}
|
||||
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #dd4a68;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
75
src/fonts/moblie/iconfont.css
Normal file
75
src/fonts/moblie/iconfont.css
Normal file
@@ -0,0 +1,75 @@
|
||||
@font-face {
|
||||
font-family: mobilefont; /* Project id 4841764 */
|
||||
src:
|
||||
url('iconfont.woff2?t=1741575354833') format('woff2'),
|
||||
url('iconfont.woff?t=1741575354833') format('woff'),
|
||||
url('iconfont.ttf?t=1741575354833') format('truetype');
|
||||
}
|
||||
|
||||
.mobilefont {
|
||||
font-style: normal;
|
||||
font-size: 18px;
|
||||
font-family: mobilefont !important;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-radiobox::before {
|
||||
content: '\e75b';
|
||||
}
|
||||
|
||||
.icon-juzhendafen::before {
|
||||
content: '\e641';
|
||||
}
|
||||
|
||||
.icon-checkbox-checked::before {
|
||||
content: '\e6c3';
|
||||
}
|
||||
|
||||
.icon-nps::before {
|
||||
content: '\e6b0';
|
||||
}
|
||||
|
||||
.icon-input::before {
|
||||
content: '\e6fd';
|
||||
}
|
||||
|
||||
.icon-juzhentiankong::before {
|
||||
content: '\e62e';
|
||||
}
|
||||
|
||||
.icon-wenjianshangchuan::before {
|
||||
content: '\e631';
|
||||
}
|
||||
|
||||
.icon-qianming::before {
|
||||
content: '\e661';
|
||||
}
|
||||
|
||||
.icon-tuwen::before {
|
||||
content: '\e62c';
|
||||
}
|
||||
|
||||
.icon-juzhenduoxuan::before {
|
||||
content: '\e818';
|
||||
}
|
||||
|
||||
.icon-juzhendanxuan::before {
|
||||
content: '\13c7f';
|
||||
}
|
||||
|
||||
.icon-edit2::before {
|
||||
content: '\e630';
|
||||
}
|
||||
|
||||
.icon-copy::before {
|
||||
content: '\e632';
|
||||
}
|
||||
|
||||
.icon-delete::before {
|
||||
content: '\e63f';
|
||||
}
|
||||
|
||||
.icon-sort::before {
|
||||
content: '\e6a0';
|
||||
}
|
||||
67
src/fonts/moblie/iconfont.js
Normal file
67
src/fonts/moblie/iconfont.js
Normal file
File diff suppressed because one or more lines are too long
114
src/fonts/moblie/iconfont.json
Normal file
114
src/fonts/moblie/iconfont.json
Normal file
@@ -0,0 +1,114 @@
|
||||
{
|
||||
"id": "4841764",
|
||||
"name": "yl",
|
||||
"font_family": "iconfont",
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "240132",
|
||||
"name": "radio_box",
|
||||
"font_class": "radiobox",
|
||||
"unicode": "e75b",
|
||||
"unicode_decimal": 59227
|
||||
},
|
||||
{
|
||||
"icon_id": "844024",
|
||||
"name": "矩阵打分",
|
||||
"font_class": "juzhendafen",
|
||||
"unicode": "e641",
|
||||
"unicode_decimal": 58945
|
||||
},
|
||||
{
|
||||
"icon_id": "1176868",
|
||||
"name": "checkbox-checked",
|
||||
"font_class": "checkbox-checked",
|
||||
"unicode": "e6c3",
|
||||
"unicode_decimal": 59075
|
||||
},
|
||||
{
|
||||
"icon_id": "8766356",
|
||||
"name": "nps",
|
||||
"font_class": "nps",
|
||||
"unicode": "e6b0",
|
||||
"unicode_decimal": 59056
|
||||
},
|
||||
{
|
||||
"icon_id": "11215250",
|
||||
"name": "input",
|
||||
"font_class": "input",
|
||||
"unicode": "e6fd",
|
||||
"unicode_decimal": 59133
|
||||
},
|
||||
{
|
||||
"icon_id": "15969322",
|
||||
"name": "矩阵填空",
|
||||
"font_class": "juzhentiankong",
|
||||
"unicode": "e62e",
|
||||
"unicode_decimal": 58926
|
||||
},
|
||||
{
|
||||
"icon_id": "15969340",
|
||||
"name": "文件上传",
|
||||
"font_class": "wenjianshangchuan",
|
||||
"unicode": "e631",
|
||||
"unicode_decimal": 58929
|
||||
},
|
||||
{
|
||||
"icon_id": "17269853",
|
||||
"name": "签名",
|
||||
"font_class": "qianming",
|
||||
"unicode": "e661",
|
||||
"unicode_decimal": 58977
|
||||
},
|
||||
{
|
||||
"icon_id": "17373529",
|
||||
"name": "图文",
|
||||
"font_class": "tuwen",
|
||||
"unicode": "e62c",
|
||||
"unicode_decimal": 58924
|
||||
},
|
||||
{
|
||||
"icon_id": "36443758",
|
||||
"name": "矩阵多选",
|
||||
"font_class": "juzhenduoxuan",
|
||||
"unicode": "e818",
|
||||
"unicode_decimal": 59416
|
||||
},
|
||||
{
|
||||
"icon_id": "38465935",
|
||||
"name": "矩阵单选",
|
||||
"font_class": "juzhendanxuan",
|
||||
"unicode": "13c7f",
|
||||
"unicode_decimal": 81023
|
||||
},
|
||||
{
|
||||
"icon_id": "1160114",
|
||||
"name": "edit-2",
|
||||
"font_class": "edit2",
|
||||
"unicode": "e630",
|
||||
"unicode_decimal": 58928
|
||||
},
|
||||
{
|
||||
"icon_id": "1160116",
|
||||
"name": "copy",
|
||||
"font_class": "copy",
|
||||
"unicode": "e632",
|
||||
"unicode_decimal": 58930
|
||||
},
|
||||
{
|
||||
"icon_id": "1160129",
|
||||
"name": "delete",
|
||||
"font_class": "delete",
|
||||
"unicode": "e63f",
|
||||
"unicode_decimal": 58943
|
||||
},
|
||||
{
|
||||
"icon_id": "1160227",
|
||||
"name": "sort",
|
||||
"font_class": "sort",
|
||||
"unicode": "e6a0",
|
||||
"unicode_decimal": 59040
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
src/fonts/moblie/iconfont.ttf
Normal file
BIN
src/fonts/moblie/iconfont.ttf
Normal file
Binary file not shown.
BIN
src/fonts/moblie/iconfont.woff
Normal file
BIN
src/fonts/moblie/iconfont.woff
Normal file
Binary file not shown.
BIN
src/fonts/moblie/iconfont.woff2
Normal file
BIN
src/fonts/moblie/iconfont.woff2
Normal file
Binary file not shown.
@@ -9,8 +9,9 @@ export const useCommonStore = defineStore('common', {
|
||||
state: () => ({
|
||||
questionsInfo: {
|
||||
survey: {
|
||||
id: 8721,
|
||||
introduction: '<p><span style="color: #e03e2d;">【样本量要求≥60】</span></p>',
|
||||
id: '',
|
||||
introduction:
|
||||
'<p>为优化活动服务品质,烦请完成问卷,感谢配合!您的反馈至关重要!(此提示语为默认提示语,您可选择自行输入本问卷的提示语)</p>',
|
||||
pages: [
|
||||
[24, 27, 26, 1],
|
||||
[2, 3, 4, 5, 6, 7],
|
||||
@@ -18,24 +19,17 @@ export const useCommonStore = defineStore('common', {
|
||||
[15, 16, 17, 18, 19, 20, 21],
|
||||
[28, 22]
|
||||
],
|
||||
sn: '8YXK4kW5',
|
||||
sn: '',
|
||||
status: 0,
|
||||
title:
|
||||
'<p><span style="font-size: 24px;"><span style="font-family: \'PingFang SC Regular\';">液态奶产品研究标准化问卷</span><span style="font-family: \'Arial Unicode MS\';">-</span><span style="font-family: \'PingFang SC Regular\';">概念测试(内测标准版)</span></span></p>',
|
||||
detail_pages: [
|
||||
[24, 27, 26, 1],
|
||||
[2, 3, 4, 5, 6, 7],
|
||||
[8, 9, 10, 11, 12, 13, 14],
|
||||
[15, 16, 17, 18, 19, 20, 21],
|
||||
[28, 22]
|
||||
],
|
||||
title: '<p>问卷标题</p>',
|
||||
detail_pages: [],
|
||||
group_pages: [],
|
||||
is_one_page_one_question: 0,
|
||||
last_question_index: 0,
|
||||
is_three_d_permissions: 0,
|
||||
is_dept: 1,
|
||||
last_title: 'Q5',
|
||||
project_name: '概念诊断问卷示例-0227',
|
||||
project_name: '',
|
||||
quota_end_content:
|
||||
'<p style="text-align:center"><img style="width:220px;margin-top:30px;margin-bottom: 40px;" src="https://cxp-pubcos.yili.com/prod-yls/theme/XxgQ98WN/1693807609602_962_error.png"></p>\n<p style="text-align:center;font-size: 16px;font-weight: 500;padding-bottom: 12px;/* margin-bottom: 10px; */">很抱歉,本次调研不太适合您的情况,感谢您的参与!</p>',
|
||||
quota_end_url: '',
|
||||
|
||||
29
src/utils/QuestionJsons/FileUpload.js
Normal file
29
src/utils/QuestionJsons/FileUpload.js
Normal file
@@ -0,0 +1,29 @@
|
||||
export default {
|
||||
id: '',
|
||||
question_type: 18,
|
||||
question_index: 41,
|
||||
stem: '请上传文件',
|
||||
title: 'Q14',
|
||||
options: [],
|
||||
last_option_index: 0,
|
||||
config: {
|
||||
is_required: 1,
|
||||
quick_type: 0,
|
||||
is_show: [],
|
||||
select_random: 0,
|
||||
min_number: 1,
|
||||
max_number: 1,
|
||||
min_size: 0,
|
||||
max_size: 1,
|
||||
is_file: 0,
|
||||
file_type: '0'
|
||||
},
|
||||
associate: [],
|
||||
question_code: '',
|
||||
logic_config: {
|
||||
order: 0,
|
||||
type: 0,
|
||||
expect: '',
|
||||
stay_time: ''
|
||||
}
|
||||
};
|
||||
@@ -1,14 +1,14 @@
|
||||
export default {
|
||||
// JSON 需要修改
|
||||
id: '',
|
||||
question_type: 5,
|
||||
question_type: '',
|
||||
question_index: '',
|
||||
stem: '请完成打分',
|
||||
stem: '请每行选择一个选项',
|
||||
title: '',
|
||||
options: [
|
||||
[
|
||||
{
|
||||
id: 'e46f51b1-bfd8-4d9c-becc-4fb7d175a6f4',
|
||||
id: '',
|
||||
is_fixed: 0,
|
||||
is_other: 0,
|
||||
is_remove_other: 0,
|
||||
@@ -25,6 +25,83 @@ export default {
|
||||
type: 0,
|
||||
cascade: [],
|
||||
config: []
|
||||
},
|
||||
{
|
||||
id: '',
|
||||
is_fixed: 0,
|
||||
is_other: 0,
|
||||
is_remove_other: 0,
|
||||
option: '<p>选项2</p>',
|
||||
option_config: {
|
||||
image_url: [],
|
||||
title: '',
|
||||
instructions: [],
|
||||
option_type: 0,
|
||||
limit_right_content: ''
|
||||
},
|
||||
option_index: 1,
|
||||
parent_id: 0,
|
||||
type: 0,
|
||||
cascade: [],
|
||||
config: []
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
option: '<p style="text-align:center">列标签1</p>',
|
||||
id: '1049201',
|
||||
type: 2,
|
||||
is_other: 0,
|
||||
is_fixed: 0,
|
||||
is_remove_other: 0,
|
||||
created_at: null,
|
||||
created_user_id: null,
|
||||
parent_id: null,
|
||||
option_index: 3,
|
||||
list_id: 74491,
|
||||
option_code: '',
|
||||
option_config: {
|
||||
title: '',
|
||||
instructions: [],
|
||||
price: 0,
|
||||
gradient: '',
|
||||
image_url: [],
|
||||
option_type: 0,
|
||||
type: 0,
|
||||
limit_right_content: '',
|
||||
child_area: null,
|
||||
binding_goods_id: ''
|
||||
},
|
||||
disable_option_update: null,
|
||||
cascade: []
|
||||
},
|
||||
{
|
||||
option: '<p style="text-align:center">列标签2</p>',
|
||||
id: '1049202',
|
||||
type: 2,
|
||||
is_other: 0,
|
||||
is_fixed: 0,
|
||||
is_remove_other: 0,
|
||||
created_at: null,
|
||||
created_user_id: null,
|
||||
parent_id: null,
|
||||
option_index: 4,
|
||||
list_id: 74491,
|
||||
option_code: '',
|
||||
option_config: {
|
||||
title: '',
|
||||
instructions: [],
|
||||
price: 0,
|
||||
gradient: '',
|
||||
image_url: [],
|
||||
option_type: 0,
|
||||
type: 0,
|
||||
limit_right_content: '',
|
||||
child_area: null,
|
||||
binding_goods_id: ''
|
||||
},
|
||||
disable_option_update: null,
|
||||
cascade: []
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
54
src/utils/QuestionJsons/NPS.js
Normal file
54
src/utils/QuestionJsons/NPS.js
Normal file
@@ -0,0 +1,54 @@
|
||||
export default {
|
||||
id: '',
|
||||
question_type: 106,
|
||||
question_index: 0,
|
||||
stem: '您向朋友或同事推荐我们的可能性多大?',
|
||||
title: '',
|
||||
options: [
|
||||
[
|
||||
{
|
||||
id: 'b68d45eb-d833-4b25-b0aa-2fde1310e88d',
|
||||
is_fixed: 0,
|
||||
is_other: 0,
|
||||
is_remove_other: 0,
|
||||
option: '<p>选项1</p>',
|
||||
option_config: {
|
||||
image_url: [],
|
||||
title: '',
|
||||
instructions: [],
|
||||
option_type: 0,
|
||||
limit_right_content: ''
|
||||
},
|
||||
option_index: 1,
|
||||
parent_id: 0,
|
||||
type: 0,
|
||||
cascade: [],
|
||||
config: []
|
||||
}
|
||||
]
|
||||
],
|
||||
last_option_index: 0,
|
||||
config: {
|
||||
is_required: 1,
|
||||
quick_type: 0,
|
||||
is_show: [],
|
||||
version: 2,
|
||||
prompt_left: '不可能',
|
||||
prompt_right: '极有可能',
|
||||
prompt_center: '',
|
||||
max: 10,
|
||||
min: 0,
|
||||
score_interval: 1,
|
||||
score_type: 0,
|
||||
score_way: 1,
|
||||
prompt_score: 2
|
||||
},
|
||||
associate: [],
|
||||
question_code: '',
|
||||
logic_config: {
|
||||
order: 0,
|
||||
type: 0,
|
||||
expect: '',
|
||||
stay_time: ''
|
||||
}
|
||||
};
|
||||
37
src/utils/QuestionJsons/SignQuestion.js
Normal file
37
src/utils/QuestionJsons/SignQuestion.js
Normal file
@@ -0,0 +1,37 @@
|
||||
export default {
|
||||
id: '17852690',
|
||||
title: 'Q7',
|
||||
stem: '请留下您的姓名',
|
||||
other: '',
|
||||
question_index: 10,
|
||||
question_type: 22,
|
||||
config: {
|
||||
is_required: 1,
|
||||
select_random: 0,
|
||||
float_window: 0,
|
||||
float_window_content: '',
|
||||
popup_window: 0,
|
||||
popup_window_content: '',
|
||||
is_show: [],
|
||||
quick_type: 0
|
||||
},
|
||||
created_at: '2025-03-06T15:51:13',
|
||||
created_user_id: 1281,
|
||||
updated_user_id: null,
|
||||
survey_id: 9482,
|
||||
logic_config: {
|
||||
expect: '',
|
||||
order: 0,
|
||||
type: 0,
|
||||
stay_time: ''
|
||||
},
|
||||
options: [],
|
||||
associate: [],
|
||||
logics_has: null,
|
||||
last_option_index: 0,
|
||||
question_code: '',
|
||||
question_value: '',
|
||||
question_tag: '',
|
||||
planet_id: '',
|
||||
permissions: null
|
||||
};
|
||||
22
src/utils/QuestionJsons/TextWithImages.js
Normal file
22
src/utils/QuestionJsons/TextWithImages.js
Normal file
@@ -0,0 +1,22 @@
|
||||
export default {
|
||||
id: '',
|
||||
question_type: '',
|
||||
question_index: 0,
|
||||
stem: '请认真阅读以下内容',
|
||||
title: '',
|
||||
options: [],
|
||||
last_option_index: 0,
|
||||
config: {
|
||||
is_required: 1,
|
||||
quick_type: 0,
|
||||
is_show: []
|
||||
},
|
||||
associate: [],
|
||||
question_code: '',
|
||||
logic_config: {
|
||||
order: 0,
|
||||
type: 0,
|
||||
expect: '',
|
||||
stay_time: ''
|
||||
}
|
||||
};
|
||||
@@ -4,3 +4,7 @@ export { default as checkbox } from './QuestionJsons/Checkbox.js';
|
||||
export { default as completion } from './QuestionJsons/Completion.js';
|
||||
export { default as rate } from './QuestionJsons/Rate.js';
|
||||
export { default as martrixQuestion } from './QuestionJsons/MartrixQuestion.js';
|
||||
export { default as fileUpload } from './QuestionJsons/FileUpload.js';
|
||||
export { default as textWithImages } from './QuestionJsons/TextWithImages.js';
|
||||
export { default as signQuestion } from './QuestionJsons/SignQuestion.js';
|
||||
export { default as nps } from './QuestionJsons/NPS.js';
|
||||
|
||||
@@ -87,7 +87,11 @@
|
||||
<template #action="{ element: el }">
|
||||
<div class="flex slot-actions">
|
||||
<template v-for="(item, optionIndex) in actionOptions">
|
||||
<div v-if="item.question_type.includes(el.question_type)" :key="optionIndex" class="flex">
|
||||
<div
|
||||
v-if="item.question_type.includes(el.question_type)"
|
||||
:key="optionIndex"
|
||||
class="flex"
|
||||
>
|
||||
<template v-for="(act, actIndex) in item.actions" :key="actIndex">
|
||||
<div class="flex align-center action-item" @click="actionEvent(act, el)">
|
||||
<van-icon :name="act.icon"></van-icon>
|
||||
@@ -104,8 +108,11 @@
|
||||
<!-- {{questionInfo.survey.pages.length}}-->
|
||||
<div v-if="!filterGap">
|
||||
<paging
|
||||
v-if="!element.question_type && questionInfo.survey.pages.length > 1" :info="element" :index="index"
|
||||
:active="pageIsActive(activeIndex, questionInfo.questions, element.page)" @click.stop=""
|
||||
v-if="!element.question_type && questionInfo.survey.pages.length > 1"
|
||||
:info="element"
|
||||
:index="index"
|
||||
:active="pageIsActive(activeIndex, questionInfo.questions, element.page)"
|
||||
@click.stop=""
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -114,7 +121,7 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ref, onMounted, watch } from 'vue';
|
||||
import { useCounterStore } from '@/stores/counter';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import Draggable from './components/Draggable.vue';
|
||||
@@ -130,6 +137,27 @@ import FileUpload from './components/Questions/FileUpload.vue';
|
||||
import NPS from '@/views/Design/components/Questions/NPS.vue';
|
||||
|
||||
const activeIndex = ref(-1);
|
||||
|
||||
// 获取所有的 question 列表内容
|
||||
const { filterGap, activeId } = defineProps({
|
||||
filterGap: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
activeId: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => activeId,
|
||||
(newVal) => {
|
||||
chooseQuestionId.value = newVal;
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* 工具函数
|
||||
*/
|
||||
@@ -176,15 +204,6 @@ function util() {
|
||||
};
|
||||
}
|
||||
|
||||
// 获取所有的 question 列表内容
|
||||
const { filterGap } = defineProps({
|
||||
filterGap: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
const { pageIsActive } = util();
|
||||
// 获取 Store 实例
|
||||
const counterStore = useCounterStore();
|
||||
|
||||
@@ -13,9 +13,13 @@
|
||||
<contenteditable v-model="element.stem" :active="active"></contenteditable>
|
||||
</template>
|
||||
<template #input>
|
||||
<template v-for="(item, index) in element.options" :key="index">
|
||||
<template v-for="(item, optionIndex) in element.options" :key="item.id">
|
||||
<van-radio-group v-if="element.question_type === 1">
|
||||
<option-action v-model:data="element.options[index]" :active="active" :question="element">
|
||||
<option-action
|
||||
v-model:data="element.options[optionIndex]"
|
||||
:active="active"
|
||||
:question="element"
|
||||
>
|
||||
<template #item="{ element: it, index: itIndex }">
|
||||
<van-radio
|
||||
:key="itIndex"
|
||||
|
||||
@@ -19,12 +19,11 @@
|
||||
</template>
|
||||
<template #input>
|
||||
<div v-for="(optionItem, optionItemIndex) in element.options" :key="optionItemIndex">
|
||||
<div v-for="(item, index) in optionItem" :key="index" @click="chooseOption(item)">
|
||||
<!-- <div-->
|
||||
<!-- :contenteditable="item.id === chooseId"-->
|
||||
<!-- class="van-field"-->
|
||||
<!-- v-html="item.option"-->
|
||||
<!-- ></div>-->
|
||||
<div
|
||||
v-for="(item, optionIndex) in optionItem"
|
||||
:key="optionIndex"
|
||||
@click="chooseOption(item)"
|
||||
>
|
||||
<RateCharacter :config="element.config"></RateCharacter>
|
||||
<div class="tips">
|
||||
<p>{{ element.config.prompt_left }}</p>
|
||||
|
||||
@@ -19,7 +19,11 @@
|
||||
</template>
|
||||
<template #input>
|
||||
<div v-for="(optionItem, optionItemIndex) in element.options" :key="optionItemIndex">
|
||||
<div v-for="(item, index) in optionItem" :key="index" @click="chooseOption(item)">
|
||||
<div
|
||||
v-for="(item, optionIndex) in optionItem"
|
||||
:key="optionIndex"
|
||||
@click="chooseOption(item)"
|
||||
>
|
||||
<div
|
||||
:contenteditable="item.id === chooseId"
|
||||
class="van-field"
|
||||
|
||||
@@ -15,7 +15,12 @@ const currentStep = ref(-1);
|
||||
// 保存当前状态
|
||||
const saveState = () => {
|
||||
if (!ctx || !signatureCanvas.value) return;
|
||||
const imageData = ctx.getImageData(0, 0, signatureCanvas.value.width, signatureCanvas.value.height);
|
||||
const imageData = ctx.getImageData(
|
||||
0,
|
||||
0,
|
||||
signatureCanvas.value.width,
|
||||
signatureCanvas.value.height
|
||||
);
|
||||
currentStep.value += 1;
|
||||
// 移除当前步骤之后的所有状态(处理在撤销后又进行了新的绘制的情况)
|
||||
undoStack.value.splice(currentStep.value);
|
||||
@@ -58,15 +63,13 @@ onMounted(() => {
|
||||
|
||||
// 触摸开始,开始绘制适用于移动设备
|
||||
signatureCanvas.value?.addEventListener('touchstart', (e) => {
|
||||
e.preventDefault(); // 防止页面滚动
|
||||
// 防止页面滚动
|
||||
e.preventDefault();
|
||||
isDrawing = true;
|
||||
const rect = signatureCanvas.value!.getBoundingClientRect();
|
||||
const touch = e.touches[0];
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(
|
||||
touch.clientX - rect.left,
|
||||
touch.clientY - rect.top
|
||||
);
|
||||
ctx.moveTo(touch.clientX - rect.left, touch.clientY - rect.top);
|
||||
});
|
||||
|
||||
signatureCanvas.value?.addEventListener('touchmove', (e) => {
|
||||
@@ -74,10 +77,7 @@ onMounted(() => {
|
||||
if (!isDrawing) return;
|
||||
const rect = signatureCanvas.value!.getBoundingClientRect();
|
||||
const touch = e.touches[0];
|
||||
ctx.lineTo(
|
||||
touch.clientX - rect.left,
|
||||
touch.clientY - rect.top
|
||||
);
|
||||
ctx.lineTo(touch.clientX - rect.left, touch.clientY - rect.top);
|
||||
ctx.stroke();
|
||||
});
|
||||
|
||||
@@ -97,19 +97,13 @@ onMounted(() => {
|
||||
isDrawing = true;
|
||||
const rect = signatureCanvas.value!.getBoundingClientRect();
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(
|
||||
e.clientX - rect.left,
|
||||
e.clientY - rect.top
|
||||
);
|
||||
ctx.moveTo(e.clientX - rect.left, e.clientY - rect.top);
|
||||
});
|
||||
|
||||
signatureCanvas.value?.addEventListener('mousemove', (e) => {
|
||||
if (!isDrawing) return;
|
||||
const rect = signatureCanvas.value!.getBoundingClientRect();
|
||||
ctx.lineTo(
|
||||
e.clientX - rect.left,
|
||||
e.clientY - rect.top
|
||||
);
|
||||
ctx.lineTo(e.clientX - rect.left, e.clientY - rect.top);
|
||||
ctx.stroke();
|
||||
});
|
||||
|
||||
@@ -162,11 +156,13 @@ const undo = () => {
|
||||
<van-cell>
|
||||
<div class="sign-question">
|
||||
<canvas
|
||||
ref="signatureCanvas" :width="canvasWidth" :height="canvasHeight"
|
||||
style="border: 1px solid #ccc; border-radius: 4px;"
|
||||
ref="signatureCanvas"
|
||||
:width="canvasWidth"
|
||||
:height="canvasHeight"
|
||||
style="border: 1px solid #ccc; border-radius: 4px"
|
||||
>
|
||||
</canvas>
|
||||
<div class="sign-text" :class="{ 'show': showSignText }">
|
||||
<div class="sign-text" :class="{ show: showSignText }">
|
||||
<span @click="clearCanvas">清空</span>
|
||||
<span @click="undo">撤销</span>
|
||||
<span @click="togglePen">{{ isEraser ? '画笔' : '橡皮擦' }}</span>
|
||||
@@ -222,4 +218,4 @@ const undo = () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -8,10 +8,16 @@
|
||||
|
||||
<van-cell-group inset class="result-cell">
|
||||
<div>
|
||||
<div>请输入问卷标题</div>
|
||||
<div>
|
||||
为优化活动服务品质,烦请完成问卷,感谢配合!您的反馈至关重要! (此
|
||||
提示语为默认提示语,您可选择自行输入本问卷的提示语)
|
||||
<!--问卷标题-->
|
||||
<contenteditable v-model="questionInfo.survey.title" :active="true"></contenteditable>
|
||||
</div>
|
||||
<div>
|
||||
<!-- 问卷标注-->
|
||||
<contenteditable
|
||||
v-model="questionInfo.survey.introduction"
|
||||
:active="true"
|
||||
></contenteditable>
|
||||
</div>
|
||||
|
||||
<button @click="show = true">添加题目</button>
|
||||
@@ -20,36 +26,43 @@
|
||||
|
||||
<div class="ques">
|
||||
<!-- 题目-->
|
||||
<Design @get-active-question="getActiveQuestion"></Design>
|
||||
<van-button @click="show = true">添加题目</van-button>
|
||||
<Design :active-id="activeId" @get-active-question="getActiveQuestion"></Design>
|
||||
<!-- <van-button @click="show = true">添加题目</van-button>-->
|
||||
<!-- 弹出的新增题目弹窗-->
|
||||
<van-popup v-model:show="show" round position="bottom" :style="{ height: '50%' }">
|
||||
<van-popup
|
||||
v-model:show="show"
|
||||
round
|
||||
:closeable="true"
|
||||
position="bottom"
|
||||
:style="{ maxHeight: '50%' }"
|
||||
title="添加题目"
|
||||
>
|
||||
<van-row class="ques_title">
|
||||
<van-col :span="6">添加题目</van-col>
|
||||
<van-col :span="6" :offset="12" @click="show = false">
|
||||
<van-icon name="close" />
|
||||
</van-col>
|
||||
</van-row>
|
||||
<ul>
|
||||
<li v-for="item in quesList" :key="item.type" @click="questionEvent(item)">
|
||||
<div>
|
||||
<van-icon :name="item.icon" size="20" />
|
||||
<p>{{ item.name }}</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<van-grid :gutter="10" class="ques_list">
|
||||
<van-grid-item
|
||||
v-for="item in quesList"
|
||||
:key="item.type"
|
||||
:icon="item.icon"
|
||||
icon-color="#70b936"
|
||||
:text="item.name"
|
||||
@click="questionEvent(item)"
|
||||
>
|
||||
<template #icon>
|
||||
<span class="mobilefont grid-icon" v-html="item.icon"></span>
|
||||
</template>
|
||||
</van-grid-item>
|
||||
</van-grid>
|
||||
</van-popup>
|
||||
</div>
|
||||
|
||||
<van-cell-group inset class="thanks-cell">
|
||||
<div>您已完成本次调研,感谢您的参与!</div>
|
||||
</van-cell-group>
|
||||
|
||||
<!-- 底部功能性按钮 -->
|
||||
<div class="survey-action">
|
||||
<div class="survey-action_setting">
|
||||
<van-icon name="setting" size="18" />
|
||||
<span>设置</span>
|
||||
<div class="survey-action_setting" @click="openSettingAction">
|
||||
<van-icon name="setting" size="18" class="grid-icon" />
|
||||
<span>投放设置</span>
|
||||
</div>
|
||||
<div class="survey-action_btn">
|
||||
<van-button size="small">预览</van-button>
|
||||
@@ -58,6 +71,186 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 投放设置-->
|
||||
|
||||
<van-action-sheet v-model:show="showSetting" title="">
|
||||
<template #description>
|
||||
<div class="flex flex-start">设置</div>
|
||||
</template>
|
||||
<van-cell-group :border="false" class="ml10">
|
||||
<van-cell title="每页一题" :border="false" label-align="left">
|
||||
<template #right-icon>
|
||||
<van-switch
|
||||
v-model="questionInfo.survey.is_page_one_question"
|
||||
class="option-action-sheet-switch"
|
||||
size="0.5rem"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
></van-switch>
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-divider></van-divider>
|
||||
<van-cell title="投放数量" :border="false" label-align="left">
|
||||
<template #right-icon>
|
||||
<van-switch
|
||||
v-model="questionInfo.survey.is_publish_number"
|
||||
class="option-action-sheet-switch"
|
||||
size="0.5rem"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
></van-switch>
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-cell-group
|
||||
v-if="questionInfo.survey.is_publish_number === 1"
|
||||
class="child-group"
|
||||
:border="false"
|
||||
>
|
||||
<van-field label="投放数量最大为" input-align="right">
|
||||
<template #right-icon> 份 </template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
<van-divider></van-divider>
|
||||
<van-cell title="有效期" :border="false" label-align="left">
|
||||
<template #right-icon>
|
||||
<van-switch
|
||||
v-model="questionInfo.survey.is_time"
|
||||
class="option-action-sheet-switch"
|
||||
size="0.5rem"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
></van-switch>
|
||||
</template>
|
||||
</van-cell>
|
||||
<!--有效期-->
|
||||
<van-cell-group v-if="questionInfo.survey.is_time === 1" class="child-group" :border="false">
|
||||
<van-field
|
||||
v-model="questionInfo.survey.startTime"
|
||||
is-link
|
||||
label="起始时间"
|
||||
input-align="right"
|
||||
readonly
|
||||
@click="showTimePicker('start', questionInfo.survey.startTime)"
|
||||
>
|
||||
</van-field>
|
||||
<van-field
|
||||
v-model="questionInfo.survey.endTime"
|
||||
is-link
|
||||
label="截至时间"
|
||||
input-align="right"
|
||||
readonly
|
||||
@click="showTimePicker('end', questionInfo.survey.endTime)"
|
||||
>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell title="断点续答" :border="false" label-align="left">
|
||||
<template #right-icon>
|
||||
<van-switch
|
||||
v-model="questionInfo.survey.is_breakpoint"
|
||||
class="option-action-sheet-switch"
|
||||
size="0.5rem"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
></van-switch>
|
||||
</template>
|
||||
</van-cell>
|
||||
|
||||
<van-cell
|
||||
title="企微身份获取(开启后仅支持私有化企业环境作答)"
|
||||
:border="false"
|
||||
label-align="left"
|
||||
>
|
||||
<template #right-icon>
|
||||
<van-switch
|
||||
v-model="questionInfo.survey.wework_status"
|
||||
class="option-action-sheet-switch"
|
||||
size="0.5rem"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
></van-switch>
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-divider></van-divider>
|
||||
<van-cell title="IP答题次数限制" :border="false" label-align="left">
|
||||
<template #right-icon>
|
||||
<van-switch
|
||||
v-model="questionInfo.survey.is_ip_number"
|
||||
class="option-action-sheet-switch"
|
||||
size="0.5rem"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
></van-switch>
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-cell-group v-if="questionInfo.survey.is_ip_number === 1" class="child-group">
|
||||
<van-field
|
||||
v-model="questionInfo.survey.is_number"
|
||||
label="同一个IP地址只能作答"
|
||||
:border="false"
|
||||
input-align="right"
|
||||
>
|
||||
<template #right-icon> 次 </template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
<van-cell title="设备答题次数限制" :border="false" label-align="left">
|
||||
<template #right-icon>
|
||||
<van-switch
|
||||
v-model="questionInfo.survey.is_browser_number"
|
||||
class="option-action-sheet-switch"
|
||||
size="0.5rem"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
></van-switch>
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-cell-group
|
||||
v-if="questionInfo.survey.is_browser_number === 1"
|
||||
class="child-group"
|
||||
:border="false"
|
||||
>
|
||||
<van-field
|
||||
v-model="questionInfo.survey.browser_number"
|
||||
label="同一个浏览器只能作答"
|
||||
:border="false"
|
||||
input-align="right"
|
||||
>
|
||||
<template #right-icon> 次 </template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
<van-divider></van-divider>
|
||||
<van-field
|
||||
v-model="endText"
|
||||
label="结束语"
|
||||
:border="false"
|
||||
readonly
|
||||
label-align="left"
|
||||
input-align="right"
|
||||
is-link
|
||||
@click="openEndTextModel"
|
||||
>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
</van-action-sheet>
|
||||
|
||||
<!--时间选择-->
|
||||
<van-popup v-model:show="timePickerModel" position="bottom" round>
|
||||
<YLPicker
|
||||
title=""
|
||||
:showPicker="timePickerModel"
|
||||
:values="currentDate"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
:units="['年', '月', '日', '时', '分', '秒']"
|
||||
@cancel="timePickerModel = false"
|
||||
@confirm="onConfirmDate"
|
||||
></YLPicker>
|
||||
</van-popup>
|
||||
|
||||
<!-- 结束语选择-->
|
||||
<van-popup v-model:show="textModel" position="bottom" round>
|
||||
<van-picker :columns="columns" @confirm="onConfirm"></van-picker>
|
||||
</van-popup>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -66,8 +259,19 @@ import Design from '@/views/Design/Index.vue';
|
||||
import { useCounterStore } from '@/stores/counter';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { radio, checkbox, completion, rate, martrixQuestion } from '@/utils/importJsons';
|
||||
import {
|
||||
radio,
|
||||
checkbox,
|
||||
completion,
|
||||
rate,
|
||||
martrixQuestion,
|
||||
fileUpload,
|
||||
textWithImages,
|
||||
signQuestion,
|
||||
nps
|
||||
} from '@/utils/importJsons';
|
||||
import { useRoute } from 'vue-router';
|
||||
import YLPicker from '@/components/YLPicker.vue';
|
||||
|
||||
// 获取 Store 实例
|
||||
const counterStore = useCounterStore();
|
||||
@@ -78,9 +282,62 @@ const questionInfo = ref(store.questionsInfo.value);
|
||||
|
||||
const activeQuestionIndex = ref(-1);
|
||||
|
||||
const currentDate = ref();
|
||||
const currentType = ref();
|
||||
const route = useRoute();
|
||||
const surveyTitle = route.meta.title as string;
|
||||
const show = ref(false);
|
||||
const textModel = ref(false);
|
||||
const activeId = ref(0);
|
||||
|
||||
const showSetting = ref(false);
|
||||
const timePickerModel = ref(false);
|
||||
|
||||
// picker 结束语选择器
|
||||
|
||||
const columns = ref([
|
||||
{
|
||||
text: '成功完成',
|
||||
value: '1'
|
||||
},
|
||||
{
|
||||
text: '题前终止',
|
||||
value: '2'
|
||||
},
|
||||
{
|
||||
text: '配额超限',
|
||||
value: '3'
|
||||
}
|
||||
]);
|
||||
|
||||
const endText = ref('');
|
||||
const onConfirm = (ev) => {
|
||||
endText.value = columns.value[ev.selectedValues[0] - 1].text;
|
||||
textModel.value = false;
|
||||
};
|
||||
|
||||
const openSettingAction = () => {
|
||||
showSetting.value = true;
|
||||
};
|
||||
|
||||
const showTimePicker = (type, value) => {
|
||||
timePickerModel.value = true;
|
||||
currentType.value = type;
|
||||
currentDate.value = value;
|
||||
};
|
||||
|
||||
const openEndTextModel = () => {
|
||||
textModel.value = true;
|
||||
};
|
||||
|
||||
const onConfirmDate = (e) => {
|
||||
if (currentType.value === 'start') {
|
||||
questionInfo.value.survey.startTime = e;
|
||||
} else {
|
||||
questionInfo.value.survey.endTime = e;
|
||||
}
|
||||
timePickerModel.value = false;
|
||||
};
|
||||
|
||||
// 获取选中的题目
|
||||
const getActiveQuestion = (activeQues) => {
|
||||
@@ -95,21 +352,21 @@ const getActiveQuestion = (activeQues) => {
|
||||
|
||||
const quesList = ref([
|
||||
{
|
||||
icon: 'location-o',
|
||||
icon: '',
|
||||
name: '单选题',
|
||||
question_type: '1',
|
||||
json: radio
|
||||
},
|
||||
{
|
||||
icon: 'like-o',
|
||||
icon: '',
|
||||
name: '多选题',
|
||||
question_type: '2',
|
||||
question_type: 2,
|
||||
json: checkbox
|
||||
},
|
||||
{
|
||||
icon: 'star-o',
|
||||
icon: '',
|
||||
name: '填空题',
|
||||
question_type: '3',
|
||||
question_type: 4,
|
||||
json: completion
|
||||
},
|
||||
// {
|
||||
@@ -119,89 +376,75 @@ const quesList = ref([
|
||||
// json: rate
|
||||
// },
|
||||
{
|
||||
icon: 'cart-o',
|
||||
icon: '',
|
||||
name: '数值打分',
|
||||
question_type: '4',
|
||||
question_type: 5,
|
||||
json: rate
|
||||
},
|
||||
{
|
||||
icon: 'comment-o',
|
||||
icon: '𓱿',
|
||||
name: '矩阵单选',
|
||||
question_type: '8',
|
||||
question_type: 9,
|
||||
json: martrixQuestion
|
||||
},
|
||||
{
|
||||
icon: 'bag-o',
|
||||
icon: '',
|
||||
name: '矩阵多选',
|
||||
question_type: '9',
|
||||
question_type: 10,
|
||||
json: martrixQuestion
|
||||
},
|
||||
{
|
||||
icon: 'gift-o',
|
||||
icon: '',
|
||||
name: '矩阵填空',
|
||||
question_type: '10',
|
||||
question_type: 8,
|
||||
json: martrixQuestion
|
||||
},
|
||||
{
|
||||
icon: 'bag-o',
|
||||
icon: '',
|
||||
name: '文件上传',
|
||||
question_type: '9'
|
||||
question_type: 18,
|
||||
json: fileUpload
|
||||
},
|
||||
{
|
||||
icon: 'bag-o',
|
||||
icon: '',
|
||||
name: '图文说明',
|
||||
question_type: 6,
|
||||
json: textWithImages
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
name: '签名',
|
||||
question_type: 22,
|
||||
json: signQuestion
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
name: 'NPS',
|
||||
question_type: '106'
|
||||
question_type: 106,
|
||||
json: nps
|
||||
}
|
||||
]);
|
||||
|
||||
const questionEvent = (item) => {
|
||||
let questionJson = {};
|
||||
// switch (item.question_type) {
|
||||
// // 单选 多选
|
||||
// case '1':
|
||||
// case '2':
|
||||
//
|
||||
//
|
||||
// break;
|
||||
// // 填空
|
||||
// case '3':
|
||||
// questionJson = JSON.parse(
|
||||
// JSON.stringify({
|
||||
// ...item.json,
|
||||
// id: uuidv4(),
|
||||
// question_index: questionInfo.value.survey.last_question_index + 1
|
||||
// })
|
||||
// );
|
||||
// break;
|
||||
// // 图形打分
|
||||
// case '4':
|
||||
// questionJson = JSON.parse(
|
||||
// JSON.stringify({
|
||||
// ...item.json,
|
||||
// id: uuidv4(),
|
||||
// question_index: questionInfo.value.survey.last_question_index + 1
|
||||
// })
|
||||
// );
|
||||
// break
|
||||
// }
|
||||
|
||||
const id = uuidv4();
|
||||
questionJson = JSON.parse(
|
||||
JSON.stringify({
|
||||
...item.json,
|
||||
id: uuidv4(),
|
||||
id,
|
||||
question_type: Number(item.question_type),
|
||||
question_index: questionInfo.value.survey.last_question_index + 1,
|
||||
options:
|
||||
item.json.options.length > 0
|
||||
? item.json.options.map((item) => {
|
||||
return item.map((it) => {
|
||||
return {
|
||||
...it,
|
||||
// 主键生成
|
||||
id: uuidv4()
|
||||
};
|
||||
});
|
||||
})
|
||||
return item.map((it) => {
|
||||
return {
|
||||
...it,
|
||||
// 主键生成
|
||||
id: uuidv4()
|
||||
};
|
||||
});
|
||||
})
|
||||
: []
|
||||
})
|
||||
);
|
||||
@@ -213,6 +456,8 @@ const questionEvent = (item) => {
|
||||
}
|
||||
// 更新题目索引
|
||||
questionInfo.value.survey.last_question_index += 1;
|
||||
activeId.value = id;
|
||||
show.value = false;
|
||||
};
|
||||
|
||||
const init = () => {
|
||||
@@ -257,34 +502,41 @@ defineExpose({ init });
|
||||
}
|
||||
|
||||
.thanks-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 70px;
|
||||
//display: flex;
|
||||
//align-items: center;
|
||||
//justify-content: center;
|
||||
//height: 70px;
|
||||
margin: 10px 5px;
|
||||
}
|
||||
|
||||
.grid-icon {
|
||||
color: #70b936;
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
.ques {
|
||||
.ques_title {
|
||||
margin: 20px 0 10px;
|
||||
margin: 20px 0 10px 20px;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
padding: 10px;
|
||||
.ques_list {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
width: 80px;
|
||||
margin: 5px;
|
||||
padding: 10px;
|
||||
background-color: #f7fbf5;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
}
|
||||
.child-group {
|
||||
& ::v-deep .van-field__label {
|
||||
width: 140px;
|
||||
color: #bfbfbf;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
& ::v-deep .van-cell__title {
|
||||
width: 140px;
|
||||
color: #bfbfbf;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,9 +546,11 @@ defineExpose({ init });
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
|
||||
//margin: 0 10px;
|
||||
background-color: white;
|
||||
|
||||
.survey-action_setting {
|
||||
@@ -304,14 +558,20 @@ defineExpose({ init });
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 10%;
|
||||
margin-left: 10px;
|
||||
|
||||
//width: 10%;
|
||||
}
|
||||
|
||||
.survey-action_btn {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
width: 60%;
|
||||
justify-content: space-between;
|
||||
margin-right: 10px;
|
||||
|
||||
& .van-button + .van-button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user