| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707 |
- <template>
- <uni-forms ref="taskForm" :modelValue="taskFormData" :label-width="250" label-position="top" :rules="taskFormRules">
- <!-- 基本描述 -->
- <uni-section title="基本描述" padding="16px" type="line">
- <uni-forms-item label="任务名称" required name="taskName">
- <uni-easyinput v-model="taskFormData.taskName" placeholder="请输入任务名称" />
- </uni-forms-item>
- <uni-forms-item label="规则描述" name="description">
- <uni-easyinput type="textarea" v-model="taskFormData.description" placeholder="请输入任务描述" />
- </uni-forms-item>
- </uni-section>
- <!-- 显示配置 -->
- <uni-section title="显示配置" padding="16px" type="line">
- <uni-forms-item label="显示顺序" required name="displayOrder">
- <uni-easyinput v-model="taskFormData.displayOrder" placeholder="显示顺序" type="number" />
- </uni-forms-item>
- <uni-forms-item label="开始显示时间" required name="displayTime">
- <picker mode="time" :value="taskFormData.displayTime" @change="displayTimeChange">
- <view class="pick-box">{{ taskFormData.displayTime }}</view>
- </picker>
- </uni-forms-item>
- </uni-section>
- <!-- 重复配置 -->
- <uni-section title="重复配置" padding="16px" type="line">
- <uni-forms-item label="重复周期类型" required name="repeatCategory">
- <uni-data-select :localdata="repeatCategorySelectedData"
- v-model="taskFormData.repeatCategory"></uni-data-select>
- </uni-forms-item>
- <uni-forms-item label="自定义重复日" required name="repeatCustomDay"
- v-if="taskFormData.repeatCategory == REPEAT_CATEGORY.CUSTOM">
- <uni-data-checkbox multiple :localdata="repeatCustomDaySelectedData"
- v-model="taskFormData.repeatCustomDay"></uni-data-checkbox>
- </uni-forms-item>
- </uni-section>
- <!-- 打卡配置 -->
- <uni-section title="打卡配置" padding="16px" type="line">
- <uni-forms-item label="打卡方式" required name="punchInMethod">
- <uni-data-select :localdata="punchInMethodSelectedData" v-model="taskFormData.punchInMethod"></uni-data-select>
- </uni-forms-item>
- <uni-forms-item label="判断规则" required name="compareRule"
- v-if="taskFormData.punchInMethod == PUNCH_IN_METHOD.COUNT || taskFormData.punchInMethod == PUNCH_IN_METHOD.TIMING">
- <uni-data-select :localdata="compareRuleSelectedData" v-model="taskFormData.compareRule"></uni-data-select>
- </uni-forms-item>
- <uni-forms-item label="数值" required name="countTrack" v-if="taskFormData.punchInMethod == PUNCH_IN_METHOD.COUNT">
- <uni-easyinput v-model="taskFormData.countTrack" placeholder="请输入目标数值" type="digit" />
- </uni-forms-item>
- <uni-forms-item label="时间" required name="timeTrack" v-if="taskFormData.punchInMethod == PUNCH_IN_METHOD.TIMING">
- <picker mode="time" :value="taskFormData.timeTrack" @change="timeChange">
- <view class="pick-box">{{ taskFormData.timeTrack }}</view>
- </picker>
- </uni-forms-item>
- </uni-section>
- <!-- 积分配置 -->
- <uni-section title="积分配置" padding="16px" type="line">
- <uni-forms-item label="奖励积分(基本)" required name="points">
- <uni-easyinput v-model="taskFormData.points" placeholder="请输入奖励积分(基本)" type="number" />
- </uni-forms-item>
- <uni-forms-item label="额外奖励方式" required name="extraMethod">
- <uni-data-select :localdata="extraMethodSelectedData" v-model="taskFormData.extraMethod"></uni-data-select>
- </uni-forms-item>
- <uni-forms-item label="额外的时间间隔(单位:分钟)" required name="extraTimeStep"
- v-if="taskFormData.extraMethod != EXTRA_METHOD.NONE && taskFormData.punchInMethod == PUNCH_IN_METHOD.TIMING">
- <uni-easyinput v-model="taskFormData.extraTimeStep" placeholder="额外的时间间隔(单位:分钟)" type="number" />
- </uni-forms-item>
- <uni-forms-item label="奖励的积分(额外)" required name="extraPoints"
- v-if="taskFormData.extraMethod == EXTRA_METHOD.FIXED">
- <uni-easyinput v-model="taskFormData.extraPoints" placeholder="奖励的积分(额外)" type="number" />
- </uni-forms-item>
- <uni-forms-item label="积分区间" required :rules="[{ 'required': true, errorMessage: '起始值必填' }]"
- :name="['taskExtList', index, 'extraPoints', 'value']" v-if="taskFormData.extraMethod == EXTRA_METHOD.INTERVAL">
- <template v-for="(item, index) in taskFormData.taskExtList" :key="item.id">
- <view class="extra-box">
- <view class="extra-box-item">
- <uni-easyinput v-model="taskFormData.taskExtList[index].initialValue.value" placeholder="请输入起始值" />
- </view>
- <view class="extra-box-item">
- <uni-easyinput v-model="taskFormData.taskExtList[index].extraPoints.value" placeholder="请输入奖励积分" />
- </view>
- <button class="button extra-box-btn" size="mini" type="default" @click="deleteTaskExt(item.id)">删除</button>
- </view>
- </template>
- </uni-forms-item>
- <button type="primary" size="mini" @click="addTaskExt()"
- v-if="taskFormData.extraMethod == EXTRA_METHOD.INTERVAL">新增拓展信息</button>
- </uni-section>
- <!-- 节假日配置 -->
- <uni-section title="节假日配置" padding="16px" type="line">
- <uni-forms-item label="节假日双倍" required name="holidayStatus">
- <uni-data-select v-model="taskFormData.holidayStatus"
- :localdata="commonEnabledStatusSelectedData"></uni-data-select>
- </uni-forms-item>
- <uni-forms-item label="数值(节假日)" required name="holidayCountTrack"
- v-if="taskFormData.holidayStatus == COMMON_ENABLED_STATUS.ENABLED && taskFormData.punchInMethod == PUNCH_IN_METHOD.COUNT">
- <uni-easyinput v-model="taskFormData.holidayCountTrack" placeholder="请输入目标数值" type="digit" />
- </uni-forms-item>
- <uni-forms-item label="时间(节假日)" required name="holidayTimeTrack"
- v-if="taskFormData.holidayStatus == COMMON_ENABLED_STATUS.ENABLED && taskFormData.punchInMethod == PUNCH_IN_METHOD.TIMING">
- <picker mode="time" :value="taskFormData.holidayTimeTrack" @change="holidayTimeChange">
- <view class="pick-box">{{ taskFormData.holidayTimeTrack }}</view>
- </picker>
- </uni-forms-item>
- </uni-section>
- <!-- 全勤配置 -->
- <uni-section title="全勤配置" padding="16px" type="line">
- <uni-forms-item label="全勤双倍" required name="fullAttendanceStatus">
- <uni-data-select v-model="taskFormData.fullAttendanceStatus"
- :localdata="commonEnabledStatusSelectedData"></uni-data-select>
- </uni-forms-item>
- <uni-forms-item label="全勤周期" required name="fullAttendancePeriod"
- v-if="taskFormData.fullAttendanceStatus == COMMON_ENABLED_STATUS.ENABLED">
- <uni-data-select :localdata="fullAttendancePeriodSelectedData"
- v-model="taskFormData.fullAttendancePeriod"></uni-data-select>
- </uni-forms-item>
- <uni-forms-item label="容错次数" required name="fullAttendancefaulttoleranceCnt"
- v-if="taskFormData.fullAttendanceStatus == COMMON_ENABLED_STATUS.ENABLED">
- <uni-easyinput v-model="taskFormData.fullAttendancefaulttoleranceCnt" placeholder="请输入目标数值" type="digit" />
- </uni-forms-item>
- </uni-section>
- <!-- 连续规则配置 -->
- <uni-section title="连续规则配置" padding="16px" type="line">
- <uni-forms-item label="是否启用连续规则" required name="continueStatus">
- <uni-data-select :localdata="commonEnabledStatusSelectedData"
- v-model="taskFormData.continueStatus"></uni-data-select>
- </uni-forms-item>
- <uni-forms-item label="宽限期(单位:天)" required name="graceDay"
- v-if="taskFormData.continueStatus == COMMON_ENABLED_STATUS.ENABLED">
- <uni-easyinput v-model="taskFormData.graceDay" placeholder="宽限期(单位:天)" type="number" />
- </uni-forms-item>
- <uni-forms-item label="连续中断次数" required name="continueInterruptedCount"
- v-if="taskFormData.continueStatus == COMMON_ENABLED_STATUS.ENABLED">
- <uni-easyinput v-model="taskFormData.continueInterruptedCount" placeholder="连续中断次数" type="number" />
- </uni-forms-item>
- <uni-forms-item label="惩罚天数(单位:天)" required name="penaltyDay"
- v-if="taskFormData.continueStatus == COMMON_ENABLED_STATUS.ENABLED">
- <uni-easyinput v-model="taskFormData.penaltyDay" placeholder="惩罚天数(单位:天)" type="number" />
- </uni-forms-item>
- </uni-section>
- <!-- 任务整体配置 -->
- <uni-section title="任务整体配置" padding="16px" type="line">
- <uni-forms-item label="任务自动归档时间(结束)" name="endDate">
- <uni-datetime-picker type="date" return-type="date" v-model="taskFormData.endDate" />
- </uni-forms-item>
- <uni-forms-item label="是否启用自动打卡" required name="autoStatus">
- <uni-data-select :localdata="commonEnabledStatusSelectedData"
- v-model="taskFormData.autoStatus"></uni-data-select>
- </uni-forms-item>
- <uni-forms-item label="是否启用任务积分计算" required name="taskPointsStatus">
- <uni-data-select :localdata="commonEnabledStatusSelectedData"
- v-model="taskFormData.taskPointsStatus"></uni-data-select>
- </uni-forms-item>
- <uni-forms-item label="积分区间" required :rules="[{ 'required': true, errorMessage: '起始值必填' }]"
- :name="['continueTaskExtList', index, 'extraPoints', 'value']"
- v-if="taskFormData.taskPointsStatus == COMMON_ENABLED_STATUS.ENABLED">
- <template v-for="(item, index) in taskFormData.continueTaskExtList" :key="item.id">
- <view class="extra-box">
- <view class="extra-box-item">
- <uni-easyinput v-model="taskFormData.continueTaskExtList[index].initialValue.value"
- placeholder="请输入起始值" />
- </view>
- <view class="extra-box-item">
- <uni-easyinput v-model="taskFormData.continueTaskExtList[index].extraPoints.value"
- placeholder="请输入奖励积分" />
- </view>
- <button class="button extra-box-btn" size="mini" type="default"
- @click="deleteContinueTaskExt(item.id)">删除</button>
- </view>
- </template>
- </uni-forms-item>
- <button type="primary" size="mini" @click="addContinueTaskExt()"
- v-if="taskFormData.taskPointsStatus == COMMON_ENABLED_STATUS.ENABLED">新增拓展信息</button>
- </uni-section>
- <!-- 按钮组 -->
- <view class="button-container">
- <button type="default" style="width:300rpx;" @click="cancel()">取消</button>
- <button type="primary" style="color:#ffffff;backgroundColor:#2A82E4;width:300rpx;" @click="saveTask()">保存</button>
- </view>
- </uni-forms>
- </template>
- <script setup>
- import { ref } from 'vue';
- import { onLoad } from '@dcloudio/uni-app';
- import { punchInApi } from '@/apis/apis';
- import { PUNCH_IN_METHOD, COMMON_ENABLED_STATUS, COMPARE_RULE, EXTRA_METHOD, REPEAT_CATEGORY } from '@/common/enums';
- // 组件
- /**
- * 打卡任务表单
- */
- const taskForm = ref(null);
- // 属性
- /**
- * 打卡任务表单数据
- */
- const taskFormData = ref({
- "repeatCategory": REPEAT_CATEGORY.EVERYDAY,
- "punchInMethod": PUNCH_IN_METHOD.SINGLE,
- "extraMethod": EXTRA_METHOD.NONE,
- "holidayStatus": COMMON_ENABLED_STATUS.DISABLED,
- "fullAttendanceStatus": COMMON_ENABLED_STATUS.DISABLED,
- "continueStatus": COMMON_ENABLED_STATUS.DISABLED,
- "autoStatus": COMMON_ENABLED_STATUS.DISABLED,
- "taskPointsStatus": COMMON_ENABLED_STATUS.DISABLED,
- "taskExtList": [],
- "continueTaskExtList": []
- });
- /**
- * 打卡任务表单规则
- */
- const taskFormRules = ref({
- taskName: {
- rules: [{
- required: true,
- errorMessage: '任务名称不能为空'
- },
- {
- minLength: 2,
- maxLength: 30,
- errorMessage: '长度在 {minLength} 到 {maxLength} 个字符',
- }]
- },
- description: {
- rules: [{
- maxLength: 100,
- errorMessage: '描述不能超过 {maxLength} 个字符'
- }]
- },
- displayOrder: {
- rules: [{
- required: true,
- errorMessage: '显示顺序不能为空'
- }, {
- format: 'number',
- errorMessage: "请输入有效数字"
- }, {
- minimum: 1,
- errorMessage: "最小值{minimum}"
- }]
- },
- displayTime: {
- rules: [{
- required: true,
- errorMessage: '显示时间不能为空'
- }]
- },
- repeatCategory: {
- rules: [{
- required: true,
- errorMessage: '重复类型不能为空'
- }]
- },
- punchInMethod: {
- rules: [{
- required: true,
- errorMessage: '打卡方式不能为空'
- }]
- },
- compareRule: {
- rules: [{
- required: true,
- errorMessage: '比较规则不能为空'
- }]
- },
- countTrack: {
- rules: [{
- required: true,
- errorMessage: '数值不能为空'
- }, {
- format: 'number',
- errorMessage: "请输入有效数字"
- }, {
- minimum: 1,
- errorMessage: "最小值{minimum}"
- }]
- },
- timeTrack: {
- rules: [{
- required: true,
- errorMessage: '数值不能为空'
- }]
- },
- points: {
- rules: [{
- required: true,
- errorMessage: '奖励积分不能为空'
- }, {
- format: 'number',
- errorMessage: "请输入有效数字"
- }, {
- minimum: 1,
- errorMessage: "最小值{minimum}"
- }]
- },
- extraMethod: {
- rules: [{
- required: true,
- errorMessage: '额外奖励方式不能为空'
- }]
- },
- extraTimeStep: {
- rules: [{
- required: true,
- errorMessage: '额外的时间间隔方式不能为空'
- }, {
- format: 'number',
- errorMessage: "请输入有效数字"
- }, {
- minimum: 1,
- errorMessage: "最小值{minimum}"
- }]
- },
- extraPoints: {
- rules: [{
- required: true,
- errorMessage: '奖励的积分(额外)不能为空'
- }, {
- format: 'number',
- errorMessage: "请输入有效数字"
- }, {
- minimum: 1,
- errorMessage: "最小值{minimum}"
- }]
- },
- taskExtList: {
- rules: [{
- required: true,
- errorMessage: '积分区间不能为空'
- }]
- },
- holidayStatus: {
- rules: [{
- required: true,
- errorMessage: '节假日双倍不能为空'
- }]
- },
- holidayCountTrack: {
- rules: [{
- required: true,
- errorMessage: '数值不能为空'
- }, {
- format: 'number',
- errorMessage: "请输入有效数字"
- }, {
- minimum: 1,
- errorMessage: "最小值{minimum}"
- }]
- },
- holidayTimeTrack: {
- rules: [{
- required: true,
- errorMessage: '时间不能为空'
- }]
- },
- fullAttendanceStatus: {
- rules: [{
- required: true,
- errorMessage: '全勤奖励不能为空'
- }]
- },
- fullAttendancePeriod: {
- rules: [{
- required: true,
- errorMessage: '全勤周期不能为空'
- }]
- },
- fullAttendancefaulttoleranceCnt: {
- rules: [{
- required: true,
- errorMessage: '数值不能为空'
- }, {
- format: 'number',
- errorMessage: "请输入有效数字"
- }, {
- minimum: 1,
- errorMessage: "最小值{minimum}"
- }]
- },
- continueStatus: {
- rules: [{
- required: true,
- errorMessage: '是否启用连续规则不能为空'
- }]
- },
- graceDay: {
- rules: [{
- required: true,
- errorMessage: '数值不能为空'
- }, {
- format: 'number',
- errorMessage: "请输入有效数字"
- }, {
- minimum: 1,
- errorMessage: "最小值{minimum}"
- }]
- },
- continueInterruptedCount: {
- rules: [{
- required: true,
- errorMessage: '数值不能为空'
- }, {
- format: 'number',
- errorMessage: "请输入有效数字"
- }, {
- minimum: 1,
- errorMessage: "最小值{minimum}"
- }]
- },
- penaltyDay: {
- rules: [{
- required: true,
- errorMessage: '数值不能为空'
- }, {
- format: 'number',
- errorMessage: "请输入有效数字"
- }, {
- minimum: 1,
- errorMessage: "最小值{minimum}"
- }]
- },
- autoStatus: {
- rules: [{
- required: true,
- errorMessage: '是否启用自动打卡不能为空'
- }]
- },
- taskPointsStatus: {
- rules: [{
- required: true,
- errorMessage: '是否启用任务积分计算不能为空'
- }]
- },
- continueTaskPointsStatus: {
- rules: [{
- required: true,
- errorMessage: '是否启用任务积分计算不能为空'
- }]
- }
- });
- /**
- * 通用启用状态 下拉选择数据
- */
- const commonEnabledStatusSelectedData = ref([{
- "text": "启用",
- "value": 'ENABLED'
- }, {
- "text": "禁用",
- "value": 'DISABLED'
- }]);
- /**
- * 打卡方式 下拉选择数据
- */
- const punchInMethodSelectedData = ref([{
- "text": "单次打卡",
- "value": 'SINGLE'
- }, {
- "text": "计数",
- "value": 'COUNT'
- }, {
- "text": "计时",
- "value": 'TIMING'
- }]);
- /**
- * 比较规则 下拉选择数据
- */
- const compareRuleSelectedData = ref([{
- "text": "大于等于",
- "value": 'GTE'
- }, {
- "text": "小于等于",
- "value": 'LTE'
- }]);
- /**
- * 全勤周期 下拉选择数据
- */
- const fullAttendancePeriodSelectedData = ref([{
- "text": "周",
- "value": 'WEEK'
- }, {
- "text": "月",
- "value": 'MONTH'
- }]);
- /**
- * 重复周期类型 下拉选择数据
- */
- const repeatCategorySelectedData = ref([{
- "text": "每日",
- "value": 'EVERYDAY'
- }, {
- "text": "法定工作日",
- "value": 'WORKDAY'
- }, {
- "text": "法定节假日(含周末)",
- "value": 'HOLIDAY'
- }, {
- "text": "自定义(周一至周日)",
- "value": 'CUSTOM'
- }]);
- /**
- * 自定义重复日 下拉选择数据
- */
- const repeatCustomDaySelectedData = ref([{
- "text": "周一",
- "value": '1'
- }, {
- "text": "周二",
- "value": '2'
- }, {
- "text": "周三",
- "value": '3'
- }, {
- "text": "周四",
- "value": '4'
- }, {
- "text": "周五",
- "value": '5'
- }, {
- "text": "周六",
- "value": '6'
- }, {
- "text": "周日",
- "value": '7'
- }]);
- /**
- * 额外奖励方式 下拉选择数据
- */
- const extraMethodSelectedData = ref([{
- "text": "无",
- "value": 'NONE'
- }, {
- "text": "固定",
- "value": 'FIXED'
- }, {
- "text": "区间",
- "value": 'INTERVAL'
- }]);
- // 方法
- /**
- * 时间选择监听
- */
- const timeChange = (e) => {
- taskFormData.value.timeTrack = e.detail.value;
- }
- /**
- * 显示时间 时间选择监听
- */
- const displayTimeChange = (e) => {
- taskFormData.value.displayTIme = e.detail.value;
- }
- /**
- * 节假日时间 时间选择监听
- */
- const holidayTimeChange = (e) => {
- taskFormData.value.holidayTimeTrack = e.detail.value;
- }
- /**
- * 新增任务拓展信息
- */
- const addTaskExt = () => {
- taskFormData.value.taskExtList.push({
- id: Date.now(),
- "initialValue": {
- label: '起始值',
- value: ''
- },
- "extraPoints": {
- label: '奖励的积分(额外)',
- value: ''
- }
- })
- }
- /**
- * 删除任务拓展信息
- */
- const deleteTaskExt = (id) => {
- let index = taskFormData.value.taskExtList.findIndex(v => v.id === id)
- taskFormData.value.taskExtList.splice(index, 1)
- }
- /**
- * 新增任务拓展信息
- */
- const addContinueTaskExt = () => {
- taskFormData.value.continueTaskExtList.push({
- id: Date.now(),
- "initialValue": {
- label: '起始值',
- value: ''
- },
- "extraPoints": {
- label: '奖励的积分(额外)',
- value: ''
- }
- })
- }
- /**
- * 删除任务拓展信息
- */
- const deleteContinueTaskExt = (id) => {
- let index = taskFormData.value.continueTaskExtList.findIndex(v => v.id === id)
- taskFormData.value.continueTaskExtList.splice(index, 1)
- }
- /**
- * 保存打卡任务
- */
- const saveTask = () => {
- taskForm.value.validate(['id']).then(() => {
- return punchInApi.saveTask(taskFormData.value)
- }).then(datt => {
- uni.showToast({
- title: '保存成功',
- icon: 'success',
- duration: 2000
- });
- setTimeout(() => {
- uni.navigateBack();
- }, 2000);
- }).catch(err => {
- console.log('表单错误信息:', err);
- uni.showModal({
- title: "保存失败",
- content: "请检查表单项是否已正确填写",
- showCancel: false
- });
- });
- }
- /**
- * 后退
- */
- const cancel = () => {
- uni.navigateBack();
- }
- onLoad(async (e) => {
- if (e.id) {
- const res = await punchInApi.queryTask({ "id": e.id });
- taskFormData.value = res;
- }
- });
- </script>
- <style lang="scss" scoped>
- .extra-box {
- display: flex;
- .extra-box-item {
- flex: 1;
- }
- }
- .pick-box {
- display: flex;
- box-sizing: border-box;
- flex-direction: row;
- align-items: center;
- border: 1px solid #dcdfe6;
- border-radius: 4px;
- width: auto;
- position: relative;
- overflow: hidden;
- flex: 1;
- line-height: 1;
- font-size: 14px;
- height: 35px;
- padding-left: 10px;
- }
- .button-container {
- background-color: #FFFFFF;
- display: flex;
- /* 使用Flexbox布局 */
- justify-content: space-between;
- /* 按钮之间的空间分布 */
- padding: 20rpx;
- /* 容器两侧的空白填充 */
- }
- </style>
|